summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author Fabio Priuli <etabeta78@users.noreply.github.com>2014-10-10 15:28:46 +0000
committer Fabio Priuli <etabeta78@users.noreply.github.com>2014-10-10 15:28:46 +0000
commitf0fad04eb68b545e6075f3b65d6d4db8c03e4025 (patch)
treee1a52b526fd0a7e306fd5cfe9adac62976555823 /src/emu
parent4de494250b26fc201171ac3b2b3c24f25ac08aab (diff)
(MESS) converted vectrex and crvision to use slot devices for
their carts. nw. (with these, we are done for the moment with new slot devices for carts...)
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/bus/bus.mak24
-rw-r--r--src/emu/bus/crvision/rom.c138
-rw-r--r--src/emu/bus/crvision/rom.h114
-rw-r--r--src/emu/bus/crvision/slot.c296
-rw-r--r--src/emu/bus/crvision/slot.h107
-rw-r--r--src/emu/bus/vectrex/rom.c86
-rw-r--r--src/emu/bus/vectrex/rom.h65
-rw-r--r--src/emu/bus/vectrex/slot.c280
-rw-r--r--src/emu/bus/vectrex/slot.h114
9 files changed, 1224 insertions, 0 deletions
diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak
index 08a4be6cf19..986adb3a0b8 100644
--- a/src/emu/bus/bus.mak
+++ b/src/emu/bus/bus.mak
@@ -298,6 +298,18 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/crvision/slot.h,BUSES += CRVISION
+#-------------------------------------------------
+
+ifneq ($(filter CRVISION,$(BUSES)),)
+OBJDIRS += $(BUSOBJ)/crvision
+BUSOBJS += $(BUSOBJ)/crvision/slot.o
+BUSOBJS += $(BUSOBJ)/crvision/rom.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/dmv/dmv.h,BUSES += DMV
#-------------------------------------------------
@@ -716,6 +728,18 @@ endif
#-------------------------------------------------
#
+#@src/emu/bus/vectrex/slot.h,BUSES += VECTREX
+#-------------------------------------------------
+
+ifneq ($(filter VECTREX,$(BUSES)),)
+OBJDIRS += $(BUSOBJ)/vectrex
+BUSOBJS += $(BUSOBJ)/vectrex/slot.o
+BUSOBJS += $(BUSOBJ)/vectrex/rom.o
+endif
+
+
+#-------------------------------------------------
+#
#@src/emu/bus/vic10/exp.h,BUSES += VIC10
#-------------------------------------------------
diff --git a/src/emu/bus/crvision/rom.c b/src/emu/bus/crvision/rom.c
new file mode 100644
index 00000000000..0030851828c
--- /dev/null
+++ b/src/emu/bus/crvision/rom.c
@@ -0,0 +1,138 @@
+/***********************************************************************************************************
+
+
+ V-Tech CreatiVision cart emulation
+
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "rom.h"
+
+
+//-------------------------------------------------
+// crvision_rom_device - constructor
+//-------------------------------------------------
+
+const device_type CRVISION_ROM_4K = &device_creator<crvision_rom_device>;
+const device_type CRVISION_ROM_6K = &device_creator<crvision_rom6k_device>;
+const device_type CRVISION_ROM_8K = &device_creator<crvision_rom8k_device>;
+const device_type CRVISION_ROM_10K = &device_creator<crvision_rom10k_device>;
+const device_type CRVISION_ROM_12K = &device_creator<crvision_rom12k_device>;
+const device_type CRVISION_ROM_16K = &device_creator<crvision_rom16k_device>;
+const device_type CRVISION_ROM_18K = &device_creator<crvision_rom18k_device>;
+
+
+crvision_rom_device::crvision_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ device_crvision_cart_interface(mconfig, *this)
+{
+}
+
+crvision_rom_device::crvision_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, CRVISION_ROM_4K, "CreatiVision 4K Carts", tag, owner, clock, "crvision_4k", __FILE__),
+ device_crvision_cart_interface(mconfig, *this)
+{
+}
+
+crvision_rom6k_device::crvision_rom6k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : crvision_rom_device(mconfig, CRVISION_ROM_6K, "CreatiVision 6K Carts", tag, owner, clock, "crvision_6k", __FILE__)
+{
+}
+
+crvision_rom8k_device::crvision_rom8k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : crvision_rom_device(mconfig, CRVISION_ROM_8K, "CreatiVision 8K Carts", tag, owner, clock, "crvision_8k", __FILE__)
+{
+}
+
+crvision_rom10k_device::crvision_rom10k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : crvision_rom_device(mconfig, CRVISION_ROM_10K, "CreatiVision 10K Carts", tag, owner, clock, "crvision_10k", __FILE__)
+{
+}
+
+crvision_rom12k_device::crvision_rom12k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : crvision_rom_device(mconfig, CRVISION_ROM_12K, "CreatiVision 12K Carts", tag, owner, clock, "crvision_12k", __FILE__)
+{
+}
+
+crvision_rom16k_device::crvision_rom16k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : crvision_rom_device(mconfig, CRVISION_ROM_16K, "CreatiVision 16K Carts", tag, owner, clock, "crvision_16k", __FILE__)
+{
+}
+
+crvision_rom18k_device::crvision_rom18k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : crvision_rom_device(mconfig, CRVISION_ROM_18K, "CreatiVision 18K Carts", tag, owner, clock, "crvision_18k", __FILE__)
+{
+}
+
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+READ8_MEMBER(crvision_rom_device::read_rom80)
+{
+ offset &= 0x1fff;
+ if (offset < 0x1000)
+ return 0xff;
+
+ return m_rom[offset & 0xfff];
+}
+
+
+READ8_MEMBER(crvision_rom6k_device::read_rom80)
+{
+ offset &= 0x1fff;
+ if (offset < 0x1000)
+ return m_rom[0x1000 + (offset & 0x7ff)];
+
+ return m_rom[offset & 0xfff];
+}
+
+
+READ8_MEMBER(crvision_rom8k_device::read_rom80)
+{
+ return m_rom[offset & 0x1fff];
+}
+
+
+READ8_MEMBER(crvision_rom10k_device::read_rom80)
+{
+ return m_rom[offset & 0x1fff];
+}
+
+READ8_MEMBER(crvision_rom10k_device::read_rom40)
+{
+ return m_rom[0x2000 + (offset & 0x7ff)];
+}
+
+
+READ8_MEMBER(crvision_rom12k_device::read_rom80)
+{
+ return m_rom[offset & 0x1fff];
+}
+
+READ8_MEMBER(crvision_rom12k_device::read_rom40)
+{
+ return m_rom[0x2000 + (offset & 0xfff)];
+}
+
+
+READ8_MEMBER(crvision_rom16k_device::read_rom80)
+{
+ // lower 8K in 0xa000-0xbfff, higher 8K in 0x8000-0x9fff
+ return m_rom[offset ^ 0x2000];
+}
+
+
+READ8_MEMBER(crvision_rom18k_device::read_rom80)
+{
+ // lower 8K in 0xa000-0xbfff, higher 8K in 0x8000-0x9fff
+ return m_rom[offset ^ 0x2000];
+}
+
+READ8_MEMBER(crvision_rom18k_device::read_rom40)
+{
+ return m_rom[0x4000 + (offset & 0x7ff)];
+}
diff --git a/src/emu/bus/crvision/rom.h b/src/emu/bus/crvision/rom.h
new file mode 100644
index 00000000000..e8715d47a2c
--- /dev/null
+++ b/src/emu/bus/crvision/rom.h
@@ -0,0 +1,114 @@
+#ifndef __CRVISION_ROM_H
+#define __CRVISION_ROM_H
+
+#include "slot.h"
+
+
+// ======================> crvision_rom_device
+
+class crvision_rom_device : public device_t,
+ public device_crvision_cart_interface
+{
+public:
+ // construction/destruction
+ crvision_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+ crvision_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start() {}
+ virtual void device_reset() {}
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+// ======================> crvision_rom6k_device
+
+class crvision_rom6k_device : public crvision_rom_device
+{
+public:
+ // construction/destruction
+ crvision_rom6k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+// ======================> crvision_rom8k_device
+
+class crvision_rom8k_device : public crvision_rom_device
+{
+public:
+ // construction/destruction
+ crvision_rom8k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+// ======================> crvision_rom10k_device
+
+class crvision_rom10k_device : public crvision_rom_device
+{
+public:
+ // construction/destruction
+ crvision_rom10k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom40);
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+// ======================> crvision_rom12k_device
+
+class crvision_rom12k_device : public crvision_rom_device
+{
+public:
+ // construction/destruction
+ crvision_rom12k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom40);
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+// ======================> crvision_rom16k_device
+
+class crvision_rom16k_device : public crvision_rom_device
+{
+public:
+ // construction/destruction
+ crvision_rom16k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+// ======================> crvision_rom18k_device
+
+class crvision_rom18k_device : public crvision_rom_device
+{
+public:
+ // construction/destruction
+ crvision_rom18k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom40);
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+};
+
+
+
+
+
+// device type definition
+extern const device_type CRVISION_ROM_4K;
+extern const device_type CRVISION_ROM_6K;
+extern const device_type CRVISION_ROM_8K;
+extern const device_type CRVISION_ROM_10K;
+extern const device_type CRVISION_ROM_12K;
+extern const device_type CRVISION_ROM_16K;
+extern const device_type CRVISION_ROM_18K;
+
+
+#endif
diff --git a/src/emu/bus/crvision/slot.c b/src/emu/bus/crvision/slot.c
new file mode 100644
index 00000000000..18bcab83019
--- /dev/null
+++ b/src/emu/bus/crvision/slot.c
@@ -0,0 +1,296 @@
+/***********************************************************************************************************
+
+ V-Tech CreatiVision cart emulation
+ (through slot devices)
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "slot.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type CRVISION_CART_SLOT = &device_creator<crvision_cart_slot_device>;
+
+//**************************************************************************
+// CreatiVision Cartridges Interface
+//**************************************************************************
+
+//-------------------------------------------------
+// device_crvision_cart_interface - constructor
+//-------------------------------------------------
+
+device_crvision_cart_interface::device_crvision_cart_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_rom(NULL),
+ m_rom_size(0)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_crvision_cart_interface - destructor
+//-------------------------------------------------
+
+device_crvision_cart_interface::~device_crvision_cart_interface()
+{
+}
+
+//-------------------------------------------------
+// rom_alloc - alloc the space for the cart
+//-------------------------------------------------
+
+void device_crvision_cart_interface::rom_alloc(UINT32 size, const char *tag)
+{
+ if (m_rom == NULL)
+ {
+ astring tempstring(tag);
+ tempstring.cat(CRVSLOT_ROM_REGION_TAG);
+ m_rom = device().machine().memory().region_alloc(tempstring, size, 1, ENDIANNESS_LITTLE)->base();
+ m_rom_size = size;
+ }
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// crvision_cart_slot_device - constructor
+//-------------------------------------------------
+crvision_cart_slot_device::crvision_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, CRVISION_CART_SLOT, "APF Cartridge Slot", tag, owner, clock, "crvision_cart_slot", __FILE__),
+ device_image_interface(mconfig, *this),
+ device_slot_interface(mconfig, *this),
+ m_type(CRV_4K)
+{
+}
+
+
+//-------------------------------------------------
+// crvision_cart_slot_device - destructor
+//-------------------------------------------------
+
+crvision_cart_slot_device::~crvision_cart_slot_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void crvision_cart_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_crvision_cart_interface *>(get_card_device());
+}
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void crvision_cart_slot_device::device_config_complete()
+{
+ // set brief and instance name
+ update_names();
+}
+
+
+//-------------------------------------------------
+// APF PCB
+//-------------------------------------------------
+
+struct crvision_slot
+{
+ int pcb_id;
+ const char *slot_option;
+};
+
+// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
+static const crvision_slot slot_list[] =
+{
+ { CRV_4K, "crv_rom4k" },
+ { CRV_6K, "crv_rom6k" },
+ { CRV_8K, "crv_rom8k" },
+ { CRV_10K, "crv_rom10k" },
+ { CRV_12K, "crv_rom12k" },
+ { CRV_16K, "crv_rom16k" },
+ { CRV_18K, "crv_rom18k" }
+};
+
+static int crvision_get_pcb_id(const char *slot)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (!core_stricmp(slot_list[i].slot_option, slot))
+ return slot_list[i].pcb_id;
+ }
+
+ return 0;
+}
+
+static const char *crvision_get_slot(int type)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (slot_list[i].pcb_id == type)
+ return slot_list[i].slot_option;
+ }
+
+ return "crv_rom4k";
+}
+
+
+/*-------------------------------------------------
+ call load
+ -------------------------------------------------*/
+
+bool crvision_cart_slot_device::call_load()
+{
+ if (m_cart)
+ {
+ UINT32 size = (software_entry() == NULL) ? length() : get_software_region_length("rom");
+
+ if (size > 0x4800)
+ {
+ seterror(IMAGE_ERROR_UNSPECIFIED, "Image extends beyond the expected size for an APF cart");
+ return IMAGE_INIT_FAIL;
+ }
+
+ m_cart->rom_alloc(size, tag());
+
+ if (software_entry() == NULL)
+ fread(m_cart->get_rom_base(), size);
+ else
+ memcpy(m_cart->get_rom_base(), get_software_region("rom"), size);
+
+ if (software_entry() == NULL)
+ {
+ m_type = CRV_4K;
+
+ switch (size)
+ {
+ case 0x4800:
+ m_type = CRV_18K;
+ break;
+ case 0x4000:
+ m_type = CRV_16K;
+ break;
+ case 0x3000:
+ m_type = CRV_12K;
+ break;
+ case 0x2800:
+ m_type = CRV_10K;
+ break;
+ case 0x2000:
+ m_type = CRV_8K;
+ break;
+ case 0x1800:
+ m_type = CRV_6K;
+ break;
+ case 0x1000:
+ default:
+ break;
+ }
+ }
+ else
+ {
+ const char *pcb_name = get_feature("slot");
+ if (pcb_name)
+ m_type = crvision_get_pcb_id(pcb_name);
+ }
+
+ printf("Type: %s\n", crvision_get_slot(m_type));
+
+ return IMAGE_INIT_PASS;
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+/*-------------------------------------------------
+ call softlist load
+ -------------------------------------------------*/
+
+bool crvision_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
+{
+ load_software_part_region(*this, swlist, swname, start_entry);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------
+ get default card software
+ -------------------------------------------------*/
+
+void crvision_cart_slot_device::get_default_card_software(astring &result)
+{
+ if (open_image_file(mconfig().options()))
+ {
+ const char *slot_string = "crv_rom4k";
+ UINT32 size = core_fsize(m_file);
+ int type = CRV_4K;
+
+ switch (size)
+ {
+ case 0x4800:
+ type = CRV_18K;
+ break;
+ case 0x4000:
+ type = CRV_16K;
+ break;
+ case 0x3000:
+ type = CRV_12K;
+ break;
+ case 0x2800:
+ type = CRV_10K;
+ break;
+ case 0x2000:
+ type = CRV_8K;
+ break;
+ case 0x1800:
+ type = CRV_6K;
+ break;
+ case 0x1000:
+ default:
+ break;
+ }
+
+ slot_string = crvision_get_slot(type);
+
+ //printf("type: %s\n", slot_string);
+ clear();
+
+ result.cpy(slot_string);
+ return;
+ }
+
+ software_get_default_slot(result, "crv_rom4k");
+}
+
+/*-------------------------------------------------
+ read_rom
+ -------------------------------------------------*/
+
+READ8_MEMBER(crvision_cart_slot_device::read_rom40)
+{
+ if (m_cart)
+ return m_cart->read_rom40(space, offset);
+ else
+ return 0xff;
+}
+
+READ8_MEMBER(crvision_cart_slot_device::read_rom80)
+{
+ if (m_cart)
+ return m_cart->read_rom80(space, offset);
+ else
+ return 0xff;
+}
+
diff --git a/src/emu/bus/crvision/slot.h b/src/emu/bus/crvision/slot.h
new file mode 100644
index 00000000000..8029eba2752
--- /dev/null
+++ b/src/emu/bus/crvision/slot.h
@@ -0,0 +1,107 @@
+#ifndef __CRVISION_SLOT_H
+#define __CRVISION_SLOT_H
+
+/***************************************************************************
+ TYPE DEFINITIONS
+ ***************************************************************************/
+
+
+/* PCB */
+enum
+{
+ CRV_4K = 0,
+ CRV_6K,
+ CRV_8K,
+ CRV_10K,
+ CRV_12K,
+ CRV_16K,
+ CRV_18K
+};
+
+
+// ======================> device_crvision_cart_interface
+
+class device_crvision_cart_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_crvision_cart_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_crvision_cart_interface();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom40) { return 0xff; }
+ virtual DECLARE_READ8_MEMBER(read_rom80) { return 0xff; }
+
+ void rom_alloc(UINT32 size, const char *tag);
+ UINT8* get_rom_base() { return m_rom; }
+ UINT32 get_rom_size() { return m_rom_size; }
+
+protected:
+ // internal state
+ UINT8 *m_rom;
+ UINT32 m_rom_size;
+};
+
+
+// ======================> crvision_cart_slot_device
+
+class crvision_cart_slot_device : public device_t,
+ public device_image_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ crvision_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~crvision_cart_slot_device();
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_config_complete();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual void call_unload() {}
+ virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
+
+ int get_type() { return m_type; }
+
+ virtual iodevice_t image_type() const { return IO_CARTSLOT; }
+ virtual bool is_readable() const { return 1; }
+ virtual bool is_writeable() const { return 0; }
+ virtual bool is_creatable() const { return 0; }
+ virtual bool must_be_loaded() const { return 0; }
+ virtual bool is_reset_on_load() const { return 1; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+ virtual const char *image_interface() const { return "crvision_cart"; }
+ virtual const char *file_extensions() const { return "bin,rom"; }
+
+ // slot interface overrides
+ virtual void get_default_card_software(astring &result);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom40);
+ virtual DECLARE_READ8_MEMBER(read_rom80);
+
+protected:
+
+ int m_type;
+ device_crvision_cart_interface* m_cart;
+};
+
+
+
+// device type definition
+extern const device_type CRVISION_CART_SLOT;
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+ ***************************************************************************/
+
+#define CRVSLOT_ROM_REGION_TAG ":cart:rom"
+
+#define MCFG_CRVISION_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
+ MCFG_DEVICE_ADD(_tag, CRVISION_CART_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+
+#endif
diff --git a/src/emu/bus/vectrex/rom.c b/src/emu/bus/vectrex/rom.c
new file mode 100644
index 00000000000..ceaa76c24c7
--- /dev/null
+++ b/src/emu/bus/vectrex/rom.c
@@ -0,0 +1,86 @@
+/***********************************************************************************************************
+
+
+ GCE Vectrex cart emulation
+
+ TODO:
+ - better understand how much SRAM is expected to be present by the homebrew using
+ this cart type and use a RAM array instead of the ROM region for writes
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "rom.h"
+
+
+//-------------------------------------------------
+// vectrex_rom_device - constructor
+//-------------------------------------------------
+
+const device_type VECTREX_ROM_STD = &device_creator<vectrex_rom_device>;
+const device_type VECTREX_ROM_64K = &device_creator<vectrex_rom64k_device>;
+const device_type VECTREX_ROM_SRAM = &device_creator<vectrex_sram_device>;
+
+
+vectrex_rom_device::vectrex_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ device_vectrex_cart_interface(mconfig, *this)
+{
+}
+
+vectrex_rom_device::vectrex_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, VECTREX_ROM_STD, "Vectrex Standard Carts", tag, owner, clock, "vectrex_rom", __FILE__),
+ device_vectrex_cart_interface(mconfig, *this)
+{
+}
+
+vectrex_rom64k_device::vectrex_rom64k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : vectrex_rom_device(mconfig, VECTREX_ROM_64K, "Vectrex Carts w/ Bankswitch", tag, owner, clock, "vectrex_64k", __FILE__)
+{
+}
+
+vectrex_sram_device::vectrex_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : vectrex_rom_device(mconfig, VECTREX_ROM_SRAM, "Vectrex Carts w/ SRAM", tag, owner, clock, "vectrex_sram", __FILE__)
+{
+}
+
+
+void vectrex_rom64k_device::device_start()
+{
+ save_item(NAME(m_bank));
+}
+
+void vectrex_rom64k_device::device_reset()
+{
+ m_bank = 0;
+}
+
+
+/*-------------------------------------------------
+ mapper specific handlers
+ -------------------------------------------------*/
+
+READ8_MEMBER(vectrex_rom_device::read_rom)
+{
+ if (offset < m_rom_size)
+ return m_rom[offset];
+ else
+ return 0xff;
+}
+
+
+READ8_MEMBER(vectrex_rom64k_device::read_rom)
+{
+ return m_rom[(offset + m_bank * 0x8000) & (m_rom_size - 1)];
+}
+
+WRITE8_MEMBER(vectrex_rom64k_device::write_bank)
+{
+ m_bank = data >> 6;
+}
+
+WRITE8_MEMBER(vectrex_sram_device::write_ram)
+{
+ m_rom[offset & (m_rom_size - 1)] = data;
+}
diff --git a/src/emu/bus/vectrex/rom.h b/src/emu/bus/vectrex/rom.h
new file mode 100644
index 00000000000..c1cfbe866c8
--- /dev/null
+++ b/src/emu/bus/vectrex/rom.h
@@ -0,0 +1,65 @@
+#ifndef __VECTREX_ROM_H
+#define __VECTREX_ROM_H
+
+#include "slot.h"
+
+
+// ======================> vectrex_rom_device
+
+class vectrex_rom_device : public device_t,
+ public device_vectrex_cart_interface
+{
+public:
+ // construction/destruction
+ vectrex_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
+ vectrex_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start() {}
+ virtual void device_reset() {}
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom);
+};
+
+// ======================> vectrex_rom64k_device
+
+class vectrex_rom64k_device : public vectrex_rom_device
+{
+public:
+ // construction/destruction
+ vectrex_rom64k_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_reset();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom);
+ virtual DECLARE_WRITE8_MEMBER(write_bank);
+
+private:
+ int m_bank;
+};
+
+// ======================> vectrex_sram_device
+
+class vectrex_sram_device : public vectrex_rom_device
+{
+public:
+ // construction/destruction
+ vectrex_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // reading and writing
+ virtual DECLARE_WRITE8_MEMBER(write_ram);
+};
+
+
+
+// device type definition
+extern const device_type VECTREX_ROM_STD;
+extern const device_type VECTREX_ROM_64K;
+extern const device_type VECTREX_ROM_SRAM;
+
+
+#endif
diff --git a/src/emu/bus/vectrex/slot.c b/src/emu/bus/vectrex/slot.c
new file mode 100644
index 00000000000..b44da803f74
--- /dev/null
+++ b/src/emu/bus/vectrex/slot.c
@@ -0,0 +1,280 @@
+/***********************************************************************************************************
+
+ GCE Vectrex cart emulation
+ (through slot devices)
+
+ ***********************************************************************************************************/
+
+
+#include "emu.h"
+#include "slot.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type VECTREX_CART_SLOT = &device_creator<vectrex_cart_slot_device>;
+
+//**************************************************************************
+// Vectrex Cartridges Interface
+//**************************************************************************
+
+//-------------------------------------------------
+// device_vectrex_cart_interface - constructor
+//-------------------------------------------------
+
+device_vectrex_cart_interface::device_vectrex_cart_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig, device),
+ m_rom(NULL),
+ m_rom_size(0)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_vectrex_cart_interface - destructor
+//-------------------------------------------------
+
+device_vectrex_cart_interface::~device_vectrex_cart_interface()
+{
+}
+
+//-------------------------------------------------
+// rom_alloc - alloc the space for the cart
+//-------------------------------------------------
+
+void device_vectrex_cart_interface::rom_alloc(UINT32 size, const char *tag)
+{
+ if (m_rom == NULL)
+ {
+ astring tempstring(tag);
+ tempstring.cat(VECSLOT_ROM_REGION_TAG);
+ m_rom = device().machine().memory().region_alloc(tempstring, size, 1, ENDIANNESS_LITTLE)->base();
+ m_rom_size = size;
+ }
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// vectrex_cart_slot_device - constructor
+//-------------------------------------------------
+vectrex_cart_slot_device::vectrex_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, VECTREX_CART_SLOT, "GCE Vectrex Cartridge Slot", tag, owner, clock, "vectrex_cart_slot", __FILE__),
+ device_image_interface(mconfig, *this),
+ device_slot_interface(mconfig, *this),
+ m_type(VECTREX_STD),
+ m_vec3d(VEC3D_NONE)
+{
+}
+
+
+//-------------------------------------------------
+// vectrex_cart_slot_device - destructor
+//-------------------------------------------------
+
+vectrex_cart_slot_device::~vectrex_cart_slot_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void vectrex_cart_slot_device::device_start()
+{
+ m_cart = dynamic_cast<device_vectrex_cart_interface *>(get_card_device());
+}
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void vectrex_cart_slot_device::device_config_complete()
+{
+ // set brief and instance name
+ update_names();
+}
+
+
+//-------------------------------------------------
+// Vectrex PCB
+//-------------------------------------------------
+
+struct vectrex_slot
+{
+ int pcb_id;
+ const char *slot_option;
+};
+
+// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
+static const vectrex_slot slot_list[] =
+{
+ { VECTREX_STD, "vec_rom" },
+ { VECTREX_64K, "vec_rom64k" },
+ { VECTREX_SRAM, "vec_sram" }
+};
+
+#if 0
+static int vectrex_get_pcb_id(const char *slot)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (!core_stricmp(slot_list[i].slot_option, slot))
+ return slot_list[i].pcb_id;
+ }
+
+ return 0;
+}
+#endif
+
+static const char *vectrex_get_slot(int type)
+{
+ for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
+ {
+ if (slot_list[i].pcb_id == type)
+ return slot_list[i].slot_option;
+ }
+
+ return "vec_rom";
+}
+
+/*-------------------------------------------------
+ call load
+ -------------------------------------------------*/
+
+bool vectrex_cart_slot_device::call_load()
+{
+ if (m_cart)
+ {
+ UINT32 size = (software_entry() == NULL) ? length() : get_software_region_length("rom");
+ UINT8 *ROM;
+
+ if (size > 0x10000)
+ {
+ seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size");
+ return IMAGE_INIT_FAIL;
+ }
+
+ m_cart->rom_alloc((size < 0x1000) ? 0x1000 : size, tag());
+ ROM = m_cart->get_rom_base();
+
+ if (software_entry() == NULL)
+ fread(ROM, size);
+ else
+ memcpy(ROM, get_software_region("rom"), size);
+
+ // Verify the file is accepted by the Vectrex bios
+ if (memcmp(ROM, "g GCE", 5))
+ {
+ seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid image");
+ return IMAGE_INIT_FAIL;
+ }
+
+ // determine type
+ m_type = VECTREX_STD;
+ if (!memcmp(ROM + 0x06, "SRAM", 4))
+ m_type = VECTREX_SRAM;
+ if (size > 0x8000)
+ m_type = VECTREX_64K;
+
+ //printf("Type: %s\n", vectrex_get_slot(m_type));
+
+ // determine 3D setup (to help video setup at machine_start)
+ if (!memcmp(ROM + 0x11, "NARROW", 6) && (ROM[0x39] == 0x0c))
+ m_vec3d = VEC3D_NARROW;
+
+ if (!memcmp(ROM + 0x11, "CRAZY COASTER", 13))
+ m_vec3d = VEC3D_CCOAST;
+
+ if (!memcmp(ROM + 0x11, "3D MINE STORM", 13))
+ m_vec3d = VEC3D_MINEST;
+
+ return IMAGE_INIT_PASS;
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+/*-------------------------------------------------
+ call softlist load
+ -------------------------------------------------*/
+
+bool vectrex_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
+{
+ load_software_part_region(*this, swlist, swname, start_entry);
+ return TRUE;
+}
+
+
+/*-------------------------------------------------
+ get default card software
+ -------------------------------------------------*/
+
+void vectrex_cart_slot_device::get_default_card_software(astring &result)
+{
+ if (open_image_file(mconfig().options()))
+ {
+ const char *slot_string = "vec_rom";
+ UINT32 size = core_fsize(m_file);
+ dynamic_buffer rom(size);
+ int type = VECTREX_STD;
+
+ core_fread(m_file, rom, size);
+
+ if (!memcmp(rom + 0x06, "SRAM", 4))
+ type = VECTREX_SRAM;
+ if (size > 0x8000)
+ type = VECTREX_64K;
+
+ slot_string = vectrex_get_slot(type);
+
+ //printf("type: %s\n", slot_string);
+ clear();
+
+ result.cpy(slot_string);
+ return;
+ }
+
+ software_get_default_slot(result, "vec_rom");
+}
+
+/*-------------------------------------------------
+ read_rom
+ -------------------------------------------------*/
+
+READ8_MEMBER(vectrex_cart_slot_device::read_rom)
+{
+ if (m_cart)
+ return m_cart->read_rom(space, offset);
+ else
+ return 0xff;
+}
+
+/*-------------------------------------------------
+ write_ram
+ -------------------------------------------------*/
+
+WRITE8_MEMBER(vectrex_cart_slot_device::write_ram)
+{
+ if (m_cart)
+ m_cart->write_ram(space, offset, data);
+}
+
+/*-------------------------------------------------
+ write_bank
+ -------------------------------------------------*/
+
+WRITE8_MEMBER(vectrex_cart_slot_device::write_bank)
+{
+ if (m_cart)
+ m_cart->write_bank(space, offset, data);
+}
+
+
diff --git a/src/emu/bus/vectrex/slot.h b/src/emu/bus/vectrex/slot.h
new file mode 100644
index 00000000000..912a2147e54
--- /dev/null
+++ b/src/emu/bus/vectrex/slot.h
@@ -0,0 +1,114 @@
+#ifndef __VECTREX_SLOT_H
+#define __VECTREX_SLOT_H
+
+/***************************************************************************
+ TYPE DEFINITIONS
+ ***************************************************************************/
+
+
+/* PCB */
+enum
+{
+ VECTREX_STD = 0,
+ VECTREX_64K,
+ VECTREX_SRAM
+};
+
+// 3D setup
+enum
+{
+ VEC3D_NONE = 0,
+ VEC3D_MINEST,
+ VEC3D_CCOAST,
+ VEC3D_NARROW
+};
+
+// ======================> device_vectrex_cart_interface
+
+class device_vectrex_cart_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_vectrex_cart_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_vectrex_cart_interface();
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom) { return 0xff; }
+ virtual DECLARE_WRITE8_MEMBER(write_ram) {}
+ virtual DECLARE_WRITE8_MEMBER(write_bank) {}
+
+ void rom_alloc(UINT32 size, const char *tag);
+ UINT8* get_rom_base() { return m_rom; }
+ UINT32 get_rom_size() { return m_rom_size; }
+
+protected:
+ // internal state
+ UINT8 *m_rom;
+ UINT32 m_rom_size;
+};
+
+
+// ======================> vectrex_cart_slot_device
+
+class vectrex_cart_slot_device : public device_t,
+ public device_image_interface,
+ public device_slot_interface
+{
+public:
+ // construction/destruction
+ vectrex_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~vectrex_cart_slot_device();
+
+ // device-level overrides
+ virtual void device_start();
+ virtual void device_config_complete();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual void call_unload() {}
+ virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
+
+ int get_type() { return m_type; }
+ int get_vec3d() { return m_vec3d; }
+
+ virtual iodevice_t image_type() const { return IO_CARTSLOT; }
+ virtual bool is_readable() const { return 1; }
+ virtual bool is_writeable() const { return 0; }
+ virtual bool is_creatable() const { return 0; }
+ virtual bool must_be_loaded() const { return 0; }
+ virtual bool is_reset_on_load() const { return 1; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+ virtual const char *image_interface() const { return "vectrex_cart"; }
+ virtual const char *file_extensions() const { return "bin,gam,vec"; }
+
+ // slot interface overrides
+ virtual void get_default_card_software(astring &result);
+
+ // reading and writing
+ virtual DECLARE_READ8_MEMBER(read_rom);
+ virtual DECLARE_WRITE8_MEMBER(write_ram);
+ virtual DECLARE_WRITE8_MEMBER(write_bank);
+
+protected:
+
+ int m_type, m_vec3d;
+ device_vectrex_cart_interface* m_cart;
+};
+
+
+
+// device type definition
+extern const device_type VECTREX_CART_SLOT;
+
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+ ***************************************************************************/
+
+#define VECSLOT_ROM_REGION_TAG ":cart:rom"
+
+#define MCFG_VECTREX_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
+ MCFG_DEVICE_ADD(_tag, VECTREX_CART_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+
+#endif