Esempio n. 1
0
/* 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;
}
Esempio n. 2
0
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]));
}
Esempio n. 3
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
	}
}
Esempio n. 6
0
int image_slotexists(mess_image *img)
{
	return image_index_in_device(img) < image_device(img)->count;
}
Esempio n. 7
0
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;
	}
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}