Beispiel #1
0
/*
    This is called when the cartridge is unplugged (or the emulator is
    stopped).
*/
static DEVICE_IMAGE_UNLOAD( aes_cartridge )
{
	device_t *pcbdev;

	if (downcast<legacy_device_base *>(&image.device())->token() == NULL)
	{
		/* This means something went wrong during the pcb
           identification (e.g. one of the cartridge files was not
           found). We do not need to (and cannot) unload
           the cartridge. */
		return;
	}
	pcbdev = cartslot_get_pcb(image);

	if (pcbdev != NULL)
	{
		aes_pcb_t *pcb = get_safe_pcb_token(pcbdev);
		cartslot_t *cart = get_safe_cartslot_token(&image.device());

		//  printf("unload\n");
		if (cart->mc != NULL)
		{
			/* Remove pointers and de-big-endianize RAM contents. */
			pcb->disassemble(pcbdev->machine(), image);

			/* Close the multicart; all RAM resources will be
               written to disk */
			multicart_close(pcbdev->machine().options(), cart->mc);
			cart->mc = NULL;
		}
//      else
//          fatalerror("Lost pointer to multicart in cartridge. Report bug.");
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
static DEVICE_IMAGE_UNLOAD( cartslot )
{
	device_t *device = &image.device();
	cartslot_t *cart = get_token(device);
	const cartslot_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;
	}

	if (cart->mc != NULL)
	{
		multicart_close(device->machine().options(), cart->mc);
		cart->mc = NULL;
	}

	process_cartridge(&image, PROCESS_CLEAR);
}
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;
}