/* 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."); } }
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; }
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; }