/* reads/writes a byte; write_value is -1 for read only */ static UINT8 apple525_process_byte(mess_image *img, int write_value) { UINT8 read_value; struct apple525_disk *disk; int spinfract_divisor; int spinfract_dividend; disk = (struct apple525_disk *) image_lookuptag(img, APPLE525TAG); spinfract_dividend = (int) image_device(img)->user2; spinfract_divisor = (int) image_device(img)->user3; /* no image initialized for that drive ? */ if (!image_exists(img)) return 0xFF; /* check the spin count if reading*/ if (write_value < 0) { disk->spin_count++; disk->spin_count %= spinfract_divisor; if (disk->spin_count >= spinfract_dividend) return 0x00; } /* load track if need be */ if (disk->track_loaded == 0) apple525_load_current_track(img); /* perform the read */ read_value = disk->track_data[disk->position]; /* perform the write, if applicable */ if (write_value >= 0) { disk->track_data[disk->position] = write_value; disk->track_dirty = 1; } disk->position++; disk->position %= (sizeof(disk->track_data) / sizeof(disk->track_data[0])); /* when writing; save the current track after every full sector write */ if ((write_value >= 0) && ((disk->position % APPLE2_NIBBLE_SIZE) == 0)) apple525_save_current_track(img, FALSE); return read_value; }
const char *image_typename_id(mess_image *image) { const struct IODevice *dev; int id; static char buf[64]; dev = image_device(image); id = image_index_in_device(image); return dev->name(dev, id, buf, sizeof(buf) / sizeof(buf[0])); }
static int internal_floppy_device_load(mess_image *image, mame_file *file, int create_format, option_resolution *create_args) { floperr_t err; struct mess_flopimg *flopimg; const struct IODevice *dev; const struct FloppyFormat *floppy_options; int floppy_flags, i; const char *extension; /* look up instance data */ flopimg = get_flopimg(image); /* figure out the floppy options */ dev = image_device(image); floppy_options = device_get_info_ptr(&dev->devclass, DEVINFO_PTR_FLOPPY_OPTIONS); if (image_has_been_created(image)) { /* creating an image */ assert(create_format >= 0); err = floppy_create(file, &mess_ioprocs, &floppy_options[create_format], create_args, &flopimg->floppy); if (err) goto error; } else { /* opening an image */ floppy_flags = image_is_writable(image) ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY; extension = image_filetype(image); err = floppy_open_choices(file, &mess_ioprocs, extension, floppy_options, floppy_flags, &flopimg->floppy); if (err) goto error; } /* if we can get head and track counts, then set the geometry accordingly */ if (floppy_callbacks(flopimg->floppy)->get_heads_per_disk && floppy_callbacks(flopimg->floppy)->get_tracks_per_disk) { floppy_drive_set_geometry_absolute(image, floppy_get_tracks_per_disk(flopimg->floppy), floppy_get_heads_per_disk(flopimg->floppy)); } return INIT_PASS; error: for (i = 0; i < sizeof(errmap) / sizeof(errmap[0]); i++) { if (err == errmap[i].ferr) image_seterror(image, errmap[i].ierr, errmap[i].message); } return INIT_FAIL; }
static int image_checkhash(mess_image *image) { const game_driver *drv; const struct IODevice *dev; mame_file *file; char hash_string[HASH_BUF_SIZE]; int rc; /* this call should not be made when the image is not loaded */ assert(image->status & (IMAGE_STATUS_ISLOADING | IMAGE_STATUS_ISLOADED)); /* only calculate CRC if it hasn't been calculated, and the open_mode is read only */ if (!image->hash && !image->writeable && !image->created) { /* initialize key variables */ file = image_fp(image); dev = image_device(image); /* do not cause a linear read of 600 megs please */ /* TODO: use SHA/MD5 in the CHD header as the hash */ if (dev->type == IO_CDROM) return FALSE; if (!run_hash(file, dev->partialhash, hash_string, HASH_CRC | HASH_MD5 | HASH_SHA1)) return FALSE; image->hash = image_strdup(image, hash_string); if (!image->hash) return FALSE; /* now read the hash file */ drv = Machine->gamedrv; do { rc = read_hash_config(drv->name, image); drv = mess_next_compatible_driver(drv); } while(rc && drv); } return TRUE; }
static void command_image_loadcreate(void) { mess_image *image; int device_type; int device_slot; const char *device_tag; int i, format_index = 0; const char *filename; const char *format; char buf[128]; const struct IODevice *dev; const char *file_extensions; device_slot = current_command->u.image_args.device_slot; device_type = current_command->u.image_args.device_type; device_tag = current_command->u.image_args.device_tag; /* look up the image slot */ if (device_tag) image = image_from_devtag_and_index(device_tag, device_slot); else image = image_from_devtype_and_index(device_type, device_slot); if (!image) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Image slot '%s %i' does not exist", device_typename(device_type), device_slot); return; } dev = image_device(image); file_extensions = dev->file_extensions; /* is an image format specified? */ format = current_command->u.image_args.format; if (format) { if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format unless creating"); return; } if (!dev->createimage_options) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format for device"); return; } for (i = 0; dev->createimage_options[i].name; i++) { if (!strcmp(format, dev->createimage_options[i].name)) break; } if (!dev->createimage_options[i].name) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Unknown device '%s'", format); return; } format_index = i; file_extensions = dev->createimage_options[i].extensions; } /* figure out the filename */ filename = current_command->u.image_args.filename; if (!filename) { snprintf(buf, sizeof(buf) / sizeof(buf[0]), "%s.%s", current_testcase.name, file_extensions); make_filename_temporary(buf, sizeof(buf) / sizeof(buf[0])); filename = buf; } /* actually create or load the image */ switch(current_command->command_type) { case MESSTEST_COMMAND_IMAGE_CREATE: if (image_create(image, filename, format_index, NULL)) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Failed to create image '%s': %s", filename, image_error(image)); return; } break; case MESSTEST_COMMAND_IMAGE_LOAD: if (image_load(image, filename)) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Failed to load image '%s': %s", filename, image_error(image)); return; } break; default: break; } }
int image_slotexists(mess_image *img) { return image_index_in_device(img) < image_device(img)->count; }
static void command_image_loadcreate(void) { mess_image *image; int device_type; int device_slot; const char *device_tag; int i, format_index = 0; const char *filename; const char *format; char buf[128]; const struct IODevice *dev; const char *file_extensions; char *filepath; int success; const game_driver *gamedrv; device_slot = current_command->u.image_args.device_slot; device_type = current_command->u.image_args.device_type; device_tag = current_command->u.image_args.device_tag; /* look up the image slot */ if (device_tag) image = image_from_devtag_and_index(device_tag, device_slot); else image = image_from_devtype_and_index(device_type, device_slot); if (!image) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Image slot '%s %i' does not exist", device_typename(device_type), device_slot); return; } dev = image_device(image); file_extensions = dev->file_extensions; /* is an image format specified? */ format = current_command->u.image_args.format; if (format) { if (current_command->command_type != MESSTEST_COMMAND_IMAGE_CREATE) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format unless creating"); return; } if (!dev->createimage_options) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Cannot specify format for device"); return; } for (i = 0; dev->createimage_options[i].name; i++) { if (!strcmp(format, dev->createimage_options[i].name)) break; } if (!dev->createimage_options[i].name) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Unknown device '%s'", format); return; } format_index = i; file_extensions = dev->createimage_options[i].extensions; } /* figure out the filename */ filename = current_command->u.image_args.filename; if (!filename) { snprintf(buf, sizeof(buf) / sizeof(buf[0]), "%s.%s", current_testcase.name, file_extensions); osd_get_temp_filename(buf, ARRAY_LENGTH(buf), buf); filename = buf; } success = FALSE; for (gamedrv = Machine->gamedrv; !success && gamedrv; gamedrv = mess_next_compatible_driver(gamedrv)) { /* assemble the full path */ filepath = assemble_software_path(gamedrv, filename); /* actually create or load the image */ switch(current_command->command_type) { case MESSTEST_COMMAND_IMAGE_CREATE: success = (image_create(image, filepath, format_index, NULL) == INIT_PASS); break; case MESSTEST_COMMAND_IMAGE_LOAD: success = (image_load(image, filepath) == INIT_PASS); break; default: fatalerror("Unexpected error"); break; } free(filepath); } if (!success) { state = STATE_ABORTED; report_message(MSG_FAILURE, "Failed to load/create image '%s': %s", filename, image_error(image)); return; } }
static int image_load_internal(mess_image *img, const char *name, int is_create, int create_format, option_resolution *create_args) { const struct IODevice *dev; const char *s; char *newname; int err = INIT_PASS; mame_file *file = NULL; UINT8 *buffer = NULL; UINT64 size; unsigned int readable, writeable, creatable; /* unload if we are loaded */ if (img->status & IMAGE_STATUS_ISLOADED) image_unload(img); /* clear out the error */ image_clear_error(img); /* if we are attempting to "load" NULL, then exit at this point */ if (!name) return INIT_PASS; dev = image_device(img); assert(dev); img->status |= IMAGE_STATUS_ISLOADING; if (name && *name) { newname = image_strdup(img, name); if (!newname) { err = IMAGE_ERROR_OUTOFMEMORY; goto error; } } else newname = NULL; img->name = newname; img->dir = NULL; osd_image_load_status_changed(img, 0); /* do we need to reset the CPU? */ if ((timer_get_time() > 0) && dev->reset_on_load) machine_reset(); /* prepare to open the file */ img->created = 0; img->writeable = 0; file = NULL; if (dev->getdispositions) { dev->getdispositions(dev, image_index_in_device(img), &readable, &writeable, &creatable); } else { readable = dev->readable; writeable = dev->writeable; creatable = dev->creatable; } /* is this a ZIP file? */ s = strrchr(img->name, '.'); if (s && !mame_stricmp(s, ".ZIP")) { /* ZIP files are writeable */ writeable = 0; creatable = 0; } if (readable && !writeable) { file = image_fopen_custom(img, FILETYPE_IMAGE, OSD_FOPEN_READ); } else if (!readable && writeable) { file = image_fopen_custom(img, FILETYPE_IMAGE, OSD_FOPEN_WRITE); img->writeable = file ? 1 : 0; } else if (readable && writeable) { file = image_fopen_custom(img, FILETYPE_IMAGE, OSD_FOPEN_RW); img->writeable = file ? 1 : 0; if (!file) { file = image_fopen_custom(img, FILETYPE_IMAGE, OSD_FOPEN_READ); if (!file && creatable) { file = image_fopen_custom(img, FILETYPE_IMAGE, OSD_FOPEN_RW_CREATE); img->writeable = file ? 1 : 0; img->created = file ? 1 : 0; } } } /* did this attempt succeed? */ if (!file) { img->err = IMAGE_ERROR_FILENOTFOUND; goto error; } /* if applicable, call device verify */ if (dev->imgverify && !image_has_been_created(img)) { size = mame_fsize(file); buffer = malloc(size); if (!buffer) { img->err = IMAGE_ERROR_OUTOFMEMORY; goto error; } if (mame_fread(file, buffer, (UINT32) size) != size) { img->err = IMAGE_ERROR_INVALIDIMAGE; goto error; } err = dev->imgverify(buffer, size); if (err) { img->err = IMAGE_ERROR_INVALIDIMAGE; goto error; } mame_fseek(file, 0, SEEK_SET); free(buffer); buffer = NULL; } /* call device load or create */ if (image_has_been_created(img) && dev->create) { err = dev->create(img, file, create_format, create_args); if (err) { if (!img->err) img->err = IMAGE_ERROR_UNSPECIFIED; goto error; } } else if (dev->load) { /* using device load */ err = dev->load(img, file); if (err) { if (!img->err) img->err = IMAGE_ERROR_UNSPECIFIED; goto error; } } img->status &= ~IMAGE_STATUS_ISLOADING; img->status |= IMAGE_STATUS_ISLOADED; return INIT_PASS; error: if (file) mame_fclose(file); if (buffer) free(buffer); if (img) { img->fp = NULL; img->name = NULL; img->status &= ~IMAGE_STATUS_ISLOADING|IMAGE_STATUS_ISLOADED; } osd_image_load_status_changed(img, 0); return INIT_FAIL; }
static mame_file *image_fopen_custom(mess_image *img, int filetype, int read_or_write) { const char *sysname; char *lpExt; const game_driver *gamedrv = Machine->gamedrv; assert(img); if (!img->name) return NULL; if (img->fp) { /* If already open, we won't open the file again until it is closed. */ return NULL; } do { sysname = gamedrv->name; logerror("image_fopen: trying %s for system %s\n", img->name, sysname); img->fp = mame_fopen(sysname, img->name, filetype, read_or_write); if (img->fp && (read_or_write == OSD_FOPEN_READ)) { lpExt = strrchr( img->name, '.' ); if (lpExt && (mame_stricmp( lpExt, ".ZIP" ) == 0)) { int pathindex; int pathcount = osd_get_path_count(filetype); zip_file *zipfile; zip_entry *zipentry; char *newname; char *name; char *zipname; const char *ext; const struct IODevice *dev; mame_fclose( img->fp ); img->fp = NULL; dev = image_device(img); assert(dev); newname = NULL; zipname = image_malloc( img, strlen( sysname ) + 1 + strlen( img->name ) + 1 ); if( osd_is_absolute_path( img->name ) ) { strcpy( zipname, img->name ); } else { strcpy( zipname, sysname ); strcat( zipname, osd_path_separator() ); strcat( zipname, img->name ); } for (pathindex = 0; pathindex < pathcount; pathindex++) { zipfile = openzip(filetype, pathindex, zipname); if (zipfile) { zipentry = readzip(zipfile); while( zipentry ) { /* mess doesn't support paths in zip files */ name = osd_basename( zipentry->name ); lpExt = strrchr(name, '.'); if (lpExt) { lpExt++; ext = dev->file_extensions; while(*ext) { if( mame_stricmp( lpExt, ext ) == 0 ) { if( newname ) { image_freeptr( img, newname ); } newname = image_malloc(img, strlen(img->name) + 1 + strlen(name) + 1); if (!newname) return NULL; strcpy(newname, img->name); strcat(newname, osd_path_separator()); strcat(newname, name); } ext += strlen(ext) + 1; } } zipentry = readzip(zipfile); } closezip(zipfile); } if( !newname ) { return NULL; } img->fp = mame_fopen(sysname, newname, filetype, read_or_write); if (img->fp) { image_freeptr(img, img->name); img->name = newname; break; } } image_freeptr( img, zipname ); } } gamedrv = mess_next_compatible_driver(gamedrv); } while(!img->fp && gamedrv); if (img->fp) { logerror("image_fopen: found image %s for system %s\n", img->name, sysname); img->length = mame_fsize(img->fp); img->hash = NULL; } return img->fp; }