Removed multcart from imagedev, slots and softlists replaces this functionality (no whatsnew)

This commit is contained in:
Miodrag Milanovic 2011-11-26 08:26:58 +00:00
parent 877fd3d601
commit f37d6fb4ab
4 changed files with 0 additions and 1085 deletions

2
.gitattributes vendored
View File

@ -723,8 +723,6 @@ src/emu/imagedev/floppy.c svneol=native#text/plain
src/emu/imagedev/floppy.h svneol=native#text/plain
src/emu/imagedev/harddriv.c svneol=native#text/plain
src/emu/imagedev/harddriv.h svneol=native#text/plain
src/emu/imagedev/multcart.c svneol=native#text/plain
src/emu/imagedev/multcart.h svneol=native#text/plain
src/emu/imagedev/printer.c svneol=native#text/plain
src/emu/imagedev/printer.h svneol=native#text/plain
src/emu/imagedev/serial.c svneol=native#text/plain

View File

@ -300,7 +300,6 @@ EMUIMAGEDEVOBJS = \
$(EMUIMAGEDEV)/flopdrv.o \
$(EMUIMAGEDEV)/floppy.o \
$(EMUIMAGEDEV)/harddriv.o \
$(EMUIMAGEDEV)/multcart.o \
$(EMUIMAGEDEV)/printer.o \
$(EMUIMAGEDEV)/serial.o \
$(EMUIMAGEDEV)/snapquik.o \

View File

@ -1,888 +0,0 @@
/*********************************************************************
multcart.c
Multi-cartridge handling code
*********************************************************************/
#include "emu.h"
#include "multcart.h"
#include "pool.h"
#include "unzip.h"
#include "corestr.h"
#include "xmlfile.h"
#include "hash.h"
#include "machine/ram.h"
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
struct _multicart_private
{
object_pool * pool;
zip_file * zip;
};
typedef struct _multicart_load_state multicart_load_state;
struct _multicart_load_state
{
multicart_t * multicart;
zip_file * zip;
xml_data_node * layout_xml;
xml_data_node * resources_node;
xml_data_node * pcb_node;
multicart_resource * resources;
multicart_socket * sockets;
};
static const char error_text[14][30] =
{
"no error",
"not a multicart",
"module definition corrupt",
"out of memory",
"xml format error",
"invalid file reference",
"zip file error",
"missing ram length",
"invalid ram specification",
"unknown resource type",
"invalid resource reference",
"invalid file format",
"missing layout",
"no pcb or resource found"
};
const char *multicart_error_text(multicart_open_error error)
{
return error_text[(int)error];
}
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
INLINE multicartslot_t *get_token(device_t *device)
{
assert(device != NULL);
assert(device->type() == MULTICARTSLOT);
return (multicartslot_t *) downcast<legacy_device_base *>(device)->token();
}
INLINE const multicartslot_config *get_config(const device_t *device)
{
assert(device != NULL);
assert(device->type() == MULTICARTSLOT);
return (const multicartslot_config *) downcast<const legacy_device_base *>(device)->inline_config();
}
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
/*-------------------------------------------------
cartslot_get_pcb
-------------------------------------------------*/
device_t *cartslot_get_pcb(device_t *device)
{
multicartslot_t *cart = get_token(device);
return cart->pcb_device;
}
/*-------------------------------------------------
cartslot_get_socket
-------------------------------------------------*/
void *cartslot_get_socket(device_t *device, const char *socket_name)
{
multicartslot_t *cart = get_token(device);
device_image_interface *image = dynamic_cast<device_image_interface *>(device);
void *result = NULL;
if (cart->mc != NULL)
{
const multicart_socket *socket;
for (socket = cart->mc->sockets; socket != NULL; socket = socket->next)
{
if (!strcmp(socket->id, socket_name))
break;
}
result = socket ? socket->ptr : NULL;
}
else if (socket_name[0] == '\0')
{
result = image->ptr();
}
return result;
}
/*-------------------------------------------------
cartslot_get_resource_length
-------------------------------------------------*/
int cartslot_get_resource_length(device_t *device, const char *socket_name)
{
multicartslot_t *cart = get_token(device);
int result = 0;
if (cart->mc != NULL)
{
const multicart_socket *socket;
for (socket = cart->mc->sockets; socket != NULL; socket = socket->next)
{
if (!strcmp(socket->id, socket_name)) {
break;
}
}
if (socket != NULL)
result = socket->resource->length;
}
else
result = 0;
return result;
}
/*-------------------------------------------------
identify_pcb
-------------------------------------------------*/
static const multicartslot_pcb_type *identify_pcb(device_image_interface &image)
{
const multicartslot_config *config = get_config(&image.device());
astring pcb_name;
const multicartslot_pcb_type *pcb_type = NULL;
multicart_t *mc;
int i;
if (image.exists())
{
/* try opening this as if it were a multicart */
multicart_open_error me = multicart_open(image.device().machine().options(), image.filename(), image.device().machine().system().name, MULTICART_FLAGS_DONT_LOAD_RESOURCES, &mc);
if (me == MCERR_NONE)
{
/* this was a multicart - read from it */
astring_cpyc(&pcb_name, mc->pcb_type);
multicart_close(image.device().machine().options(), mc);
}
else
{
if (me != MCERR_NOT_MULTICART)
fatalerror("multicart error: %s", multicart_error_text(me));
}
/* look for PCB type with matching name */
for (i = 0; (i < ARRAY_LENGTH(config->pcb_types)) && (config->pcb_types[i].name != NULL); i++)
{
if ((config->pcb_types[i].name[0] == '\0') || !strcmp(astring_c(&pcb_name), config->pcb_types[i].name))
{
pcb_type = &config->pcb_types[i];
break;
}
}
/* check for unknown PCB type */
if ((mc != NULL) && (pcb_type == NULL))
fatalerror("Unknown PCB type \"%s\"", astring_c(&pcb_name));
}
else
{
/* no device loaded; use the default */
pcb_type = (config->pcb_types[0].name != NULL) ? &config->pcb_types[0] : NULL;
}
return pcb_type;
}
/*-------------------------------------------------
DEVICE_IMAGE_GET_DEVICES(cartslot)
-------------------------------------------------*/
static DEVICE_IMAGE_GET_DEVICES(multicartslot)
{
const multicartslot_pcb_type *pcb_type;
device_t *device = &image.device();
pcb_type = identify_pcb(image);
if (pcb_type != NULL)
{
image_add_device_with_subdevices(device,pcb_type->devtype,TAG_PCB,0);
}
}
/*-------------------------------------------------
find_file
-------------------------------------------------*/
static const zip_file_header *find_file(zip_file *zip, const char *filename)
{
const zip_file_header *header;
for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
{
if (!core_stricmp(header->filename, filename))
return header;
}
return NULL;
}
static const zip_file_header *find_file_crc(zip_file *zip, const char *filename, UINT32 crc)
{
const zip_file_header *header;
for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
{
// if the CRC and name both match, we're good
// if the CRC matches and the name doesn't, we're still good
if ((!core_stricmp(header->filename, filename)) && (header->crc == crc))
{
return header;
}
else if (header->crc == crc)
{
return header;
}
}
return NULL;
}
/*-------------------------------------------------
find_pcb_and_resource_nodes
-------------------------------------------------*/
static int find_pcb_and_resource_nodes(xml_data_node *layout_xml,
xml_data_node **pcb_node, xml_data_node **resource_node)
{
xml_data_node *romset_node;
xml_data_node *configuration_node;
*pcb_node = NULL;
*resource_node = NULL;
romset_node = xml_get_sibling(layout_xml->child, "romset");
if (romset_node == NULL)
return FALSE;
configuration_node = xml_get_sibling(romset_node->child, "configuration");
if (configuration_node == NULL)
return FALSE;
*pcb_node = xml_get_sibling(configuration_node->child, "pcb");
if (*pcb_node == NULL)
return FALSE;
*resource_node = xml_get_sibling(romset_node->child, "resources");
if (*resource_node == NULL)
return FALSE;
return TRUE;
}
/*-------------------------------------------------
get_resource_type
-------------------------------------------------*/
static multicart_resource_type get_resource_type(const char *s)
{
multicart_resource_type result;
if (!strcmp(s, "rom"))
result = MULTICART_RESOURCE_TYPE_ROM;
else if (!strcmp(s, "ram"))
result = MULTICART_RESOURCE_TYPE_RAM;
else
result = MULTICART_RESOURCE_TYPE_INVALID;
return result;
}
/*-------------------------------------------------
load_rom_resource
-------------------------------------------------*/
static multicart_open_error load_rom_resource(multicart_load_state *state, xml_data_node *resource_node,
multicart_resource *resource)
{
const char *file, *crcstr, *sha1;
const zip_file_header *header;
zip_error ziperr;
UINT32 crc;
/* locate the 'file' attribute */
file = xml_get_attribute_string(resource_node, "file", NULL);
if (file == NULL)
return MCERR_XML_ERROR;
if (!(crcstr = xml_get_attribute_string(resource_node, "crc", NULL)))
{
/* locate the file in the ZIP file */
header = find_file(state->zip, file);
}
else /* CRC tag is present, use it */
{
crc = strtoul(crcstr, NULL, 16);
header = find_file_crc(state->zip, file, crc);
}
if (header == NULL)
return MCERR_INVALID_FILE_REF;
resource->length = header->uncompressed_length;
/* allocate bytes for this resource */
resource->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
if (resource->ptr == NULL)
return MCERR_OUT_OF_MEMORY;
/* and decompress it */
ziperr = zip_file_decompress(state->zip, resource->ptr, resource->length);
if (ziperr != ZIPERR_NONE)
return MCERR_ZIP_ERROR;
/* check SHA1 now */
if ((sha1 = xml_get_attribute_string(resource_node, "sha1", NULL)))
{
hash_collection actual_hashes;
actual_hashes.compute((const UINT8 *)resource->ptr, resource->length, hash_collection::HASH_TYPES_CRC_SHA1);
hash_collection expected_hashes;
expected_hashes.add_from_string(hash_collection::HASH_SHA1, sha1, strlen(sha1));
if (actual_hashes != expected_hashes)
{
return MCERR_INVALID_FILE_REF;
}
}
return MCERR_NONE;
}
/*-------------------------------------------------
load_ram_resource
-------------------------------------------------*/
static multicart_open_error load_ram_resource(emu_options &options, multicart_load_state *state, xml_data_node *resource_node,
multicart_resource *resource)
{
const char *length_string;
const char *ram_type;
const char *ram_filename;
astring *ram_pathname;
/* locate the 'length' attribute */
length_string = xml_get_attribute_string(resource_node, "length", NULL);
if (length_string == NULL)
return MCERR_MISSING_RAM_LENGTH;
/* ...and parse it */
resource->length = ram_device::parse_string(length_string);
if (resource->length <= 0)
return MCERR_INVALID_RAM_SPEC;
/* allocate bytes for this resource */
resource->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
if (resource->ptr == NULL)
return MCERR_OUT_OF_MEMORY;
/* Is this a persistent RAM resource? Then try to load it. */
ram_type = xml_get_attribute_string(resource_node, "type", NULL);
if (ram_type != NULL)
{
if (strcmp(ram_type, "persistent")==0)
{
astring tmp;
/* Get the file name. */
ram_filename = xml_get_attribute_string(resource_node, "file", NULL);
if (ram_filename==NULL)
return MCERR_XML_ERROR;
ram_pathname = astring_assemble_3(&tmp, state->multicart->gamedrv_name, PATH_SEPARATOR, ram_filename);
/* Save the file name so that we can write the contents on unloading.
If the RAM resource has no filename, we know that it was volatile only. */
resource->filename = pool_strdup_lib(state->multicart->data->pool, astring_c(ram_pathname));
if (resource->filename == NULL)
return MCERR_OUT_OF_MEMORY;
image_battery_load_by_name(options, resource->filename, resource->ptr, resource->length, 0x00);
}
/* else this type is volatile, in which case we just have
a memory expansion */
}
return MCERR_NONE;
}
/*-------------------------------------------------
load_resource
-------------------------------------------------*/
static multicart_open_error load_resource(emu_options &options, multicart_load_state *state, xml_data_node *resource_node,
multicart_resource_type resource_type)
{
const char *id;
multicart_open_error err;
multicart_resource *resource;
multicart_resource **next_resource;
/* get the 'id' attribute; error if not present */
id = xml_get_attribute_string(resource_node, "id", NULL);
if (id == NULL)
return MCERR_XML_ERROR;
/* allocate memory for the resource */
resource = (multicart_resource *)pool_malloc_lib(state->multicart->data->pool, sizeof(*resource));
if (resource == NULL)
return MCERR_OUT_OF_MEMORY;
memset(resource, 0, sizeof(*resource));
resource->type = resource_type;
/* copy id */
resource->id = pool_strdup_lib(state->multicart->data->pool, id);
if (resource->id == NULL)
return MCERR_OUT_OF_MEMORY;
switch(resource->type)
{
case MULTICART_RESOURCE_TYPE_ROM:
err = load_rom_resource(state, resource_node, resource);
if (err != MCERR_NONE)
return err;
break;
case MULTICART_RESOURCE_TYPE_RAM:
err = load_ram_resource(options, state, resource_node, resource);
if (err != MCERR_NONE)
return err;
break;
default:
return MCERR_UNKNOWN_RESOURCE_TYPE;
}
/* append the resource */
for (next_resource = &state->resources; *next_resource; next_resource = &(*next_resource)->next)
;
*next_resource = resource;
return MCERR_NONE;
}
/*-------------------------------------------------
load_all_resources
-------------------------------------------------*/
static multicart_open_error load_all_resources(emu_options &options, multicart_load_state *state)
{
multicart_open_error err;
xml_data_node *resource_node;
multicart_resource_type resource_type;
for (resource_node = state->resources_node->child; resource_node != NULL; resource_node = resource_node->next)
{
resource_type = get_resource_type(resource_node->name);
if (resource_type != MULTICART_RESOURCE_TYPE_INVALID)
{
err = load_resource(options, state, resource_node, resource_type);
if (err != MCERR_NONE)
return err;
}
}
state->multicart->resources = state->resources;
return MCERR_NONE;
}
/*-------------------------------------------------
save_ram_resources. This is important for persistent RAM. All
resources were allocated within the memory pool of this device and will
be freed on multicart_close.
-------------------------------------------------*/
static multicart_open_error save_ram_resources(emu_options &options, multicart_t *cart)
{
const multicart_resource *resource;
for (resource = cart->resources; resource != NULL; resource = resource->next)
{
if ((resource->type == MULTICART_RESOURCE_TYPE_RAM) && (resource->filename != NULL))
{
image_battery_save_by_name(options, resource->filename, resource->ptr, resource->length);
}
}
return MCERR_NONE;
}
/*-------------------------------------------------
load_socket
-------------------------------------------------*/
static multicart_open_error load_socket(multicart_load_state *state, xml_data_node *socket_node)
{
const char *id;
const char *uses;
const multicart_resource *resource;
multicart_socket *socket;
multicart_socket **next_socket;
/* get the 'id' and 'uses' attributes; error if not present */
id = xml_get_attribute_string(socket_node, "id", NULL);
uses = xml_get_attribute_string(socket_node, "uses", NULL);
if ((id == NULL) || (uses == NULL))
return MCERR_XML_ERROR;
/* find the resource */
for (resource = state->multicart->resources; resource != NULL; resource = resource->next)
{
if (!strcmp(uses, resource->id))
break;
}
if (resource == NULL)
return MCERR_INVALID_RESOURCE_REF;
/* create the socket */
socket = (multicart_socket *)pool_malloc_lib(state->multicart->data->pool, sizeof(*socket));
if (socket == NULL)
return MCERR_OUT_OF_MEMORY;
memset(socket, 0, sizeof(*socket));
socket->resource = resource;
socket->ptr = resource->ptr;
/* copy id */
socket->id = pool_strdup_lib(state->multicart->data->pool, id);
if (socket->id == NULL)
return MCERR_OUT_OF_MEMORY;
/* which pointer should I use? */
if (resource->ptr != NULL)
{
/* use the resource's ptr */
socket->ptr = resource->ptr;
}
else
{
/* allocate bytes for this socket */
socket->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
if (socket->ptr == NULL)
return MCERR_OUT_OF_MEMORY;
/* ...and clear it */
memset(socket->ptr, 0xCD, resource->length);
}
/* append the resource */
for (next_socket = &state->sockets; *next_socket; next_socket = &(*next_socket)->next)
;
*next_socket = socket;
return MCERR_NONE;
}
/*-------------------------------------------------
load_all_sockets
-------------------------------------------------*/
static multicart_open_error load_all_sockets(multicart_load_state *state)
{
multicart_open_error err;
xml_data_node *socket_node;
for (socket_node = xml_get_sibling(state->pcb_node->child, "socket"); socket_node != NULL;
socket_node = xml_get_sibling(socket_node->next, "socket"))
{
err = load_socket(state, socket_node);
if (err != MCERR_NONE)
return err;
}
state->multicart->sockets = state->sockets;
return MCERR_NONE;
}
/*-------------------------------------------------
multicart_open - opens a multicart
-------------------------------------------------*/
multicart_open_error multicart_open(emu_options &options, const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart)
{
multicart_open_error err;
zip_error ziperr;
object_pool *pool;
multicart_load_state state = {0, };
const zip_file_header *header;
const char *pcb_type;
char *layout_text = NULL;
/* allocate an object pool */
pool = pool_alloc_lib(NULL);
if (pool == NULL)
{
err = MCERR_OUT_OF_MEMORY;
goto done;
}
/* allocate the multicart */
state.multicart = (multicart_t*)pool_malloc_lib(pool, sizeof(*state.multicart));
if (state.multicart == NULL)
{
err = MCERR_OUT_OF_MEMORY;
goto done;
}
memset(state.multicart, 0, sizeof(*state.multicart));
/* allocate the multicart's private data */
state.multicart->data = (multicart_private*)pool_malloc_lib(pool, sizeof(*state.multicart->data));
if (state.multicart->data == NULL)
{
err = MCERR_OUT_OF_MEMORY;
goto done;
}
memset(state.multicart->data, 0, sizeof(*state.multicart->data));
state.multicart->data->pool = pool;
pool = NULL;
/* open the ZIP file */
ziperr = zip_file_open(filename, &state.zip);
if (ziperr != ZIPERR_NONE)
{
err = MCERR_NOT_MULTICART;
goto done;
}
/* find the layout.xml file */
header = find_file(state.zip, "layout.xml");
if (header == NULL)
{
err = MCERR_MISSING_LAYOUT;
goto done;
}
/* reserve space for the layout text */
layout_text = (char*)malloc(header->uncompressed_length + 1);
if (layout_text == NULL)
{
err = MCERR_OUT_OF_MEMORY;
goto done;
}
/* uncompress the layout text */
ziperr = zip_file_decompress(state.zip, layout_text, header->uncompressed_length);
if (ziperr != ZIPERR_NONE)
{
err = MCERR_ZIP_ERROR;
goto done;
}
layout_text[header->uncompressed_length] = '\0';
/* parse the layout text */
state.layout_xml = xml_string_read(layout_text, NULL);
if (state.layout_xml == NULL)
{
err = MCERR_XML_ERROR;
goto done;
}
/* locate the PCB node */
if (!find_pcb_and_resource_nodes(state.layout_xml, &state.pcb_node, &state.resources_node))
{
err = MCERR_NO_PCB_OR_RESOURCES;
goto done;
}
/* get the PCB resource_type */
pcb_type = xml_get_attribute_string(state.pcb_node, "type", "");
state.multicart->pcb_type = pool_strdup_lib(state.multicart->data->pool, pcb_type);
if (state.multicart->pcb_type == NULL)
{
err = MCERR_OUT_OF_MEMORY;
goto done;
}
state.multicart->gamedrv_name = pool_strdup_lib(state.multicart->data->pool, gamedrv);
if (state.multicart->gamedrv_name == NULL)
{
err = MCERR_OUT_OF_MEMORY;
goto done;
}
/* do we have to load resources? */
if (load_flags & MULTICART_FLAGS_LOAD_RESOURCES)
{
err = load_all_resources(options, &state);
if (err != MCERR_NONE)
goto done;
err = load_all_sockets(&state);
if (err != MCERR_NONE)
goto done;
}
err = MCERR_NONE;
done:
if (pool != NULL)
pool_free_lib(pool);
if (state.zip != NULL)
zip_file_close(state.zip);
if (layout_text != NULL)
free(layout_text);
if (state.layout_xml != NULL)
xml_file_free(state.layout_xml);
if ((err != MCERR_NONE) && (state.multicart != NULL))
{
multicart_close(options, state.multicart);
state.multicart = NULL;
}
*cart = state.multicart;
return err;
}
/*-------------------------------------------------
multicart_close - closes a multicart
-------------------------------------------------*/
void multicart_close(emu_options &options, multicart_t *cart)
{
save_ram_resources(options, cart);
pool_free_lib(cart->data->pool);
}
/*-------------------------------------------------
DEVICE_START( multicartslot )
-------------------------------------------------*/
static DEVICE_START( multicartslot )
{
const multicartslot_config *config = get_config(device);
/* if this cartridge has a custom DEVICE_START, use it */
if (config->device_start != NULL)
{
(*config->device_start)(device);
}
}
/*-------------------------------------------------
DEVICE_IMAGE_LOAD( cartslot )
-------------------------------------------------*/
static DEVICE_IMAGE_LOAD( multicartslot )
{
device_t *device = &image.device();
const multicartslot_config *config = get_config(device);
/* if this cartridge has a custom DEVICE_IMAGE_LOAD, use it */
if (config->device_load != NULL)
return (*config->device_load)(image);
/* otherwise try the normal route */
return IMAGE_INIT_PASS;
}
/*-------------------------------------------------
DEVICE_IMAGE_UNLOAD( multicartslot )
-------------------------------------------------*/
static DEVICE_IMAGE_UNLOAD( multicartslot )
{
device_t *device = &image.device();
const multicartslot_config *config = get_config(device);
/* if this cartridge has a custom DEVICE_IMAGE_UNLOAD, use it */
if (config->device_unload != NULL)
{
(*config->device_unload)(image);
return;
}
}
/*-------------------------------------------------
DEVICE_GET_INFO( multicartslot )
-------------------------------------------------*/
DEVICE_GET_INFO( multicartslot )
{
switch(state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(multicartslot_t); break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(multicartslot_config); break;
case DEVINFO_INT_IMAGE_TYPE: info->i = IO_CARTSLOT; break;
case DEVINFO_INT_IMAGE_READABLE: info->i = 1; break;
case DEVINFO_INT_IMAGE_WRITEABLE: info->i = 0; break;
case DEVINFO_INT_IMAGE_CREATABLE: info->i = 0; break;
case DEVINFO_INT_IMAGE_RESET_ON_LOAD: info->i = 1; break;
case DEVINFO_INT_IMAGE_MUST_BE_LOADED: info->i = 0; break;
/* --- the following bits of info are returned as pointers to functions --- */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(multicartslot); break;
case DEVINFO_FCT_IMAGE_LOAD: info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(multicartslot); break;
case DEVINFO_FCT_IMAGE_UNLOAD: info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(multicartslot); break;
case DEVINFO_FCT_IMAGE_GET_DEVICES: info->f = (genf *) DEVICE_IMAGE_GET_DEVICES_NAME(multicartslot); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: strcpy(info->s, "MultiCartslot"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "MultiCartslot"); break;
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
if ( device && downcast<const legacy_image_device_base *>(device)->inline_config() && get_config(device)->extensions )
{
strcpy(info->s, get_config(device)->extensions);
}
else
{
strcpy(info->s, "bin");
}
break;
}
}
DEFINE_LEGACY_IMAGE_DEVICE(MULTICARTSLOT, multicartslot);
//**************************************************************************
// DEVICE CARTSLOT INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_cart_slot_interface - constructor
//-------------------------------------------------
device_cart_slot_interface::device_cart_slot_interface(const machine_config &mconfig, device_t &device)
: device_interface(device)
{
}
//-------------------------------------------------
// ~device_cart_slot_interface - destructor
//-------------------------------------------------
device_cart_slot_interface::~device_cart_slot_interface()
{
}
//**************************************************************************
// LIVE LEGACY cart_slot DEVICE
//**************************************************************************
//-------------------------------------------------
// legacy_cart_slot_device_base - constructor
//-------------------------------------------------
legacy_cart_slot_device_base::legacy_cart_slot_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, device_get_config_func get_config)
: legacy_device_base(mconfig, type, tag, owner, clock, get_config),
device_cart_slot_interface(mconfig, *this)
{
}

View File

@ -1,194 +0,0 @@
/*********************************************************************
multcart.h
Multi-cartridge handling code
*********************************************************************/
#ifndef __MULTCART_H__
#define __MULTCART_H__
#include "osdcore.h"
#define TAG_PCB "pcb"
DECLARE_LEGACY_IMAGE_DEVICE(MULTICARTSLOT, multicartslot);
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
enum _multicart_load_flags
{
MULTICART_FLAGS_DONT_LOAD_RESOURCES = 0x00,
MULTICART_FLAGS_LOAD_RESOURCES = 0x01
};
typedef enum _multicart_load_flags multicart_load_flags;
enum _multicart_resource_type
{
MULTICART_RESOURCE_TYPE_INVALID,
MULTICART_RESOURCE_TYPE_ROM,
MULTICART_RESOURCE_TYPE_RAM
};
typedef enum _multicart_resource_type multicart_resource_type;
typedef struct _multicart_resource multicart_resource;
struct _multicart_resource
{
const char * id;
const char * filename;
multicart_resource * next;
multicart_resource_type type;
UINT32 length;
void * ptr;
};
typedef struct _multicart_socket multicart_socket;
struct _multicart_socket
{
const char * id;
multicart_socket * next;
const multicart_resource * resource;
void * ptr;
};
typedef struct _multicart_private multicart_private;
typedef struct _multicart_t multicart_t;
struct _multicart_t
{
const multicart_resource * resources;
const multicart_socket * sockets;
const char * pcb_type;
const char * gamedrv_name; /* need this to find the path to the nvram files */
multicart_private * data;
};
typedef struct _multicartslot_t multicartslot_t;
struct _multicartslot_t
{
device_t *pcb_device;
multicart_t *mc;
};
typedef struct _multicartslot_pcb_type multicartslot_pcb_type;
struct _multicartslot_pcb_type
{
const char * name;
device_type devtype;
};
typedef struct _multicartslot_config multicartslot_config;
struct _multicartslot_config
{
const char * extensions;
device_start_func device_start;
device_image_load_func device_load;
device_image_unload_func device_unload;
multicartslot_pcb_type pcb_types[16];
};
enum _multicart_open_error
{
MCERR_NONE,
MCERR_NOT_MULTICART,
MCERR_CORRUPT,
MCERR_OUT_OF_MEMORY,
MCERR_XML_ERROR,
MCERR_INVALID_FILE_REF,
MCERR_ZIP_ERROR,
MCERR_MISSING_RAM_LENGTH,
MCERR_INVALID_RAM_SPEC,
MCERR_UNKNOWN_RESOURCE_TYPE,
MCERR_INVALID_RESOURCE_REF,
MCERR_INVALID_FILE_FORMAT,
MCERR_MISSING_LAYOUT,
MCERR_NO_PCB_OR_RESOURCES
};
typedef enum _multicart_open_error multicart_open_error;
const char *multicart_error_text(multicart_open_error error);
/***************************************************************************
PROTOTYPES
***************************************************************************/
/* opens a multicart */
multicart_open_error multicart_open(emu_options &options, const char *filename, const char *drvname, multicart_load_flags load_flags, multicart_t **cart);
/* closes a multicart */
void multicart_close(emu_options &options, multicart_t *cart);
/* accesses the PCB associated with this cartslot */
device_t *cartslot_get_pcb(device_t *device);
/* accesses a particular socket */
void *cartslot_get_socket(device_t *device, const char *socket_name);
/* accesses a particular socket; gets the length of the associated resource */
int cartslot_get_resource_length(device_t *device, const char *socket_name);
#define DECLARE_LEGACY_CART_SLOT_DEVICE(name, basename) _DECLARE_LEGACY_DEVICE(name, basename, basename##_device, legacy_cart_slot_device_base)
#define DEFINE_LEGACY_CART_SLOT_DEVICE(name, basename) _DEFINE_LEGACY_DEVICE(name, basename, basename##_device, legacy_cart_slot_device_base)
#define MCFG_MULTICARTSLOT_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, MULTICARTSLOT, 0) \
#define MCFG_MULTICARTSLOT_MODIFY(_tag) \
MCFG_DEVICE_MODIFY(_tag) \
#define MCFG_MULTICARTSLOT_PCBTYPE(_index, _pcb_type_name, _pcb_devtype) \
MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(multicartslot_config, pcb_types, _index, multicartslot_pcb_type, name, _pcb_type_name) \
MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(multicartslot_config, pcb_types, _index, multicartslot_pcb_type, devtype, _pcb_devtype)
#define MCFG_MULTICARTSLOT_START(_start) \
MCFG_DEVICE_CONFIG_DATAPTR(multicartslot_config, device_start, DEVICE_START_NAME(_start))
#define MCFG_MULTICARTSLOT_LOAD(_load) \
MCFG_DEVICE_CONFIG_DATAPTR(multicartslot_config, device_load, DEVICE_IMAGE_LOAD_NAME(_load))
#define MCFG_MULTICARTSLOT_UNLOAD(_unload) \
MCFG_DEVICE_CONFIG_DATAPTR(multicartslot_config, device_unload, DEVICE_IMAGE_UNLOAD_NAME(_unload))
#define MCFG_MULTICARTSLOT_EXTENSION_LIST(_extensions) \
MCFG_DEVICE_CONFIG_DATAPTR(multicartslot_config, extensions, _extensions)
// ======================> device_cart_slot_interface
// class representing interface-specific live cart_slot
class device_cart_slot_interface : public device_interface
{
public:
// construction/destruction
device_cart_slot_interface(const machine_config &mconfig, device_t &device);
virtual ~device_cart_slot_interface();
};
// ======================> legacy_cart_slot_device
// legacy_cart_slot_device is a legacy_device_base with a cart_slot interface
class legacy_cart_slot_device_base : public legacy_device_base,
public device_cart_slot_interface
{
protected:
// construction/destruction
legacy_cart_slot_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, device_get_config_func get_config);
public:
using legacy_device_base::get_legacy_int;
using legacy_device_base::get_legacy_fct;
using legacy_device_base::get_legacy_ptr;
// device_cart_slot_interface overrides
};
#endif /* __MULTCART_H__ */