Пример #1
0
static const char *internal_device_instancename(const device_class *devclass, int id,
	UINT32 base, const char *(*get_dev_typename)(iodevice_t))
{
	iodevice_t type;
	int count;
	const char *result;
	char *s;

	/* retrieve info about the device instance */
	result = device_get_info_string(devclass, base + id);
	if (!result)
	{
		/* not specified? default to device names based on the device type */
		type = (iodevice_t) (int) device_get_info_int(devclass, DEVINFO_INT_TYPE);
		count = (int) device_get_info_int(devclass, DEVINFO_INT_COUNT);
		result = get_dev_typename(type);

		/* need to number if there is more than one device */
		if (count > 1)
		{
			s = device_temp_str();
			sprintf(s, "%s%d", result, id + 1);
			result = s;
		}
	}
	return result;
}
Пример #2
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;
	const struct IODevice *dev;

	disk = (struct apple525_disk *) image_lookuptag(img, APPLE525TAG);
	dev = image_device(img);
	spinfract_dividend = (int) device_get_info_int(&dev->devclass, DEVINFO_INT_APPLE525_SPINFRACT_DIVIDEND);
	spinfract_divisor = (int) device_get_info_int(&dev->devclass, DEVINFO_INT_APPLE525_SPINFRACT_DIVISOR);

	/* 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;
}
Пример #3
0
static cassette_state get_default_state(const struct IODevice *dev)
{
	assert(dev->type == IO_CASSETTE);
	return (cassette_state) (int) device_get_info_int(&dev->devclass, DEVINFO_INT_CASSETTE_DEFAULT_STATE);
}
Пример #4
0
struct IODevice *devices_allocate(const game_driver *gamedrv)
{
	struct SystemConfigurationParamBlock params;
	device_getinfo_handler handlers[64];
	int count_overrides[sizeof(handlers) / sizeof(handlers[0])];
	int createimage_optcount, count, i, j, position;
	const char *file_extensions, *info_string;
	char *converted_file_extensions;
	struct IODevice *devices = NULL;

	memset(handlers, 0, sizeof(handlers));
	memset(count_overrides, 0, sizeof(count_overrides));

	if (gamedrv->sysconfig_ctor)
	{
		memset(&params, 0, sizeof(params));
		params.device_slotcount = sizeof(handlers) / sizeof(handlers[0]);
		params.device_handlers = handlers;
		params.device_countoverrides = count_overrides;
		gamedrv->sysconfig_ctor(&params);
	}

	/* count the amount of handlers that we have available */
	for (count = 0; handlers[count]; count++)
		;
	count++; /* for our purposes, include the tailing empty device */

	devices = (struct IODevice *) auto_malloc(count * sizeof(struct IODevice));
	memset(devices, 0, count * sizeof(struct IODevice));

	position = 0;

	for (i = 0; i < count; i++)
	{
		devices[i].type = IO_COUNT;

		if (handlers[i])
		{
			devices[i].devclass.get_info = handlers[i];
			devices[i].devclass.gamedrv = gamedrv;
			
			/* convert file extensions from comma delimited to null delimited */
			converted_file_extensions = NULL;
			file_extensions = device_get_info_string(&devices[i].devclass, DEVINFO_STR_FILE_EXTENSIONS);
			if (file_extensions)
			{
				converted_file_extensions = auto_malloc(strlen(file_extensions) + 2);
				for (j = 0; file_extensions[j]; j++)
					converted_file_extensions[j] = (file_extensions[j] != ',') ? file_extensions[j] : '\0';
				converted_file_extensions[j + 0] = '\0';
				converted_file_extensions[j + 1] = '\0';
			}
			
			info_string = device_get_info_string(&devices[i].devclass, DEVINFO_STR_DEV_TAG);
			devices[i].tag					= info_string ? auto_strdup(info_string) : NULL;
			devices[i].type					= device_get_info_int(&devices[i].devclass, DEVINFO_INT_TYPE);
			devices[i].count				= device_get_info_int(&devices[i].devclass, DEVINFO_INT_COUNT);
			devices[i].position				= position;
			devices[i].file_extensions		= converted_file_extensions;

			devices[i].readable				= device_get_info_int(&devices[i].devclass, DEVINFO_INT_READABLE) ? 1 : 0;
			devices[i].writeable			= device_get_info_int(&devices[i].devclass, DEVINFO_INT_WRITEABLE) ? 1 : 0;
			devices[i].creatable			= device_get_info_int(&devices[i].devclass, DEVINFO_INT_CREATABLE) ? 1 : 0;
			devices[i].reset_on_load		= device_get_info_int(&devices[i].devclass, DEVINFO_INT_RESET_ON_LOAD) ? 1 : 0;
			devices[i].must_be_loaded		= device_get_info_int(&devices[i].devclass, DEVINFO_INT_MUST_BE_LOADED) ? 1 : 0;
			devices[i].load_at_init			= device_get_info_int(&devices[i].devclass, DEVINFO_INT_LOAD_AT_INIT) ? 1 : 0;
			devices[i].not_working			= device_get_info_int(&devices[i].devclass, DEVINFO_INT_NOT_WORKING) ? 1 : 0;

			devices[i].init					= (device_init_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_INIT);
			devices[i].exit					= (device_exit_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_EXIT);
			devices[i].load					= (device_load_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_LOAD);
			devices[i].create				= (device_create_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_CREATE);
			devices[i].unload				= (device_unload_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_UNLOAD);
			devices[i].imgverify			= (device_verify_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_VERIFY);
			devices[i].partialhash			= (device_partialhash_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_PARTIAL_HASH);
			devices[i].getdispositions		= (device_getdispositions_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_GET_DISPOSITIONS);

			devices[i].display				= (device_display_handler) device_get_info_fct(&devices[i].devclass, DEVINFO_PTR_DISPLAY);
			devices[i].name					= default_device_name;

			devices[i].createimage_optguide	= (const struct OptionGuide *) device_get_info_ptr(&devices[i].devclass, DEVINFO_PTR_CREATE_OPTGUIDE);
			
			createimage_optcount = (int) device_get_info_int(&devices[i].devclass, DEVINFO_INT_CREATE_OPTCOUNT);
			if (createimage_optcount > 0)
			{
				if (createimage_optcount > DEVINFO_CREATE_OPTMAX)
					fatalerror("DEVINFO_INT_CREATE_OPTCOUNT: Too many options");

				devices[i].createimage_options = auto_malloc((createimage_optcount + 1) *
					sizeof(*devices[i].createimage_options));

				for (j = 0; j < createimage_optcount; j++)
				{
					info_string = device_get_info_string(&devices[i].devclass, DEVINFO_STR_CREATE_OPTNAME + j);
					devices[i].createimage_options[j].name			= info_string ? auto_strdup(info_string) : NULL;
					info_string = device_get_info_string(&devices[i].devclass, DEVINFO_STR_CREATE_OPTDESC + j);
					devices[i].createimage_options[j].description	= info_string ? auto_strdup(info_string) : NULL;
					info_string = device_get_info_string(&devices[i].devclass, DEVINFO_STR_CREATE_OPTEXTS + j);
					devices[i].createimage_options[j].extensions	= info_string ? auto_strdup(info_string) : NULL;
					devices[i].createimage_options[j].optspec		= device_get_info_ptr(&devices[i].devclass, DEVINFO_PTR_CREATE_OPTSPEC + j);
				}

				/* terminate the list */
				memset(&devices[i].createimage_options[createimage_optcount], 0,
					sizeof(devices[i].createimage_options[createimage_optcount]));
			}

			position += devices[i].count;

			/* overriding the count? */
			if (count_overrides[i])
				devices[i].count = count_overrides[i];

			/* any problems? */
			if ((devices[i].type < 0) || (devices[i].type >= IO_COUNT))
				goto error;
			if ((devices[i].count < 0) || (devices[i].count > MAX_DEV_INSTANCES))
				goto error;

			/* fill in defaults */
			if (!devices[i].getdispositions)
				devices[i].getdispositions = default_device_getdispositions;
		}
	}

	return devices;

error:
	return NULL;
}
Пример #5
0
static int validate_device(const device_class *devclass)
{
    int error = 0;
    int is_invalid, i;
    const char *s;
    INT64 devcount, optcount;
    char buf[256];
    char *s1;
    char *s2;
    iodevice_t devtype;
    int (*validity_check)(const device_class *devclass);

    /* critical information */
    devtype = (iodevice_t) (int) device_get_info_int(devclass, DEVINFO_INT_TYPE);
    devcount = device_get_info_int(devclass, DEVINFO_INT_COUNT);

    /* sanity check device type */
    if (devtype >= IO_COUNT)
    {
        printf("%s: invalid device type %i\n", devclass->gamedrv->name, (int) devtype);
        error = 1;
    }

    /* sanity check device count */
    if ((devcount <= 0) || (devcount > MAX_DEV_INSTANCES))
    {
        printf("%s: device type '%s' has an invalid device count %i\n", devclass->gamedrv->name, device_typename(devtype), (int) devcount);
        error = 1;
    }

    /* File Extensions Checks
     *
     * Checks the following
     *
     * 1.  Tests the integrity of the string list
     * 2.  Checks for duplicate extensions
     * 3.  Makes sure that all extensions are either lower case chars or numbers
     */
    s = device_get_info_string(devclass, DEVINFO_STR_FILE_EXTENSIONS);
    if (!s)
    {
        printf("%s: device type '%s' has null file extensions\n", devclass->gamedrv->name, device_typename(devtype));
        error = 1;
    }
    else
    {
        memset(buf, 0, sizeof(buf));
        strcpy(buf, s);

        /* convert to be null delimited */
        s1 = buf;
        while(*s1)
        {
            if (*s1 == ',')
                *s1 = '\0';
            s1++;
        }

        s1 = buf;
        while(*s1)
        {
            /* check for invalid chars */
            is_invalid = 0;
            for (s2 = s1; *s2; s2++)
            {
                if (!isdigit(*s2) && !islower(*s2))
                    is_invalid = 1;
            }
            if (is_invalid)
            {
                printf("%s: device type '%s' has an invalid extension '%s'\n", devclass->gamedrv->name, device_typename(devtype), s1);
                error = 1;
            }
            s2++;

            /* check for dupes */
            is_invalid = 0;
            while(*s2)
            {
                if (!strcmp(s1, s2))
                    is_invalid = 1;
                s2 += strlen(s2) + 1;
            }
            if (is_invalid)
            {
                printf("%s: device type '%s' has duplicate extensions '%s'\n", devclass->gamedrv->name, device_typename(devtype), s1);
                error = 1;
            }

            s1 += strlen(s1) + 1;
        }
    }

    /* enforce certain rules for certain device types */
    switch(devtype)
    {
    case IO_QUICKLOAD:
    case IO_SNAPSHOT:
        if (devcount != 1)
        {
            printf("%s: there can only be one instance of devices of type '%s'\n", devclass->gamedrv->name, device_typename(devtype));
            error = 1;
        }
    /* fallthrough */

    case IO_CARTSLOT:
        if (!device_get_info_int(devclass, DEVINFO_INT_READABLE)
                || device_get_info_int(devclass, DEVINFO_INT_WRITEABLE)
                || device_get_info_int(devclass, DEVINFO_INT_CREATABLE))
        {
            printf("%s: devices of type '%s' has invalid open modes\n", devclass->gamedrv->name, device_typename(devtype));
            error = 1;
        }
        break;

    default:
        break;
    }

    /* check creation options */
    optcount = device_get_info_int(devclass, DEVINFO_INT_CREATE_OPTCOUNT);
    if ((optcount < 0) || (optcount >= DEVINFO_CREATE_OPTMAX))
    {
        printf("%s: device type '%s' has an invalid creation optcount\n", devclass->gamedrv->name, device_typename(devtype));
        error = 1;
    }
    else
    {
        for (i = 0; i < (int) optcount; i++)
        {
            if (!device_get_info_string(devclass, DEVINFO_STR_CREATE_OPTNAME + i))
            {
                printf("%s: device type '%s' create option #%d: name not present\n",
                       devclass->gamedrv->name, device_typename(devtype), i);
                error = 1;
            }
            if (!device_get_info_string(devclass, DEVINFO_STR_CREATE_OPTDESC + i))
            {
                printf("%s: device type '%s' create option #%d: description not present\n",
                       devclass->gamedrv->name, device_typename(devtype), i);
                error = 1;
            }
            if (!device_get_info_string(devclass, DEVINFO_STR_CREATE_OPTEXTS + i))
            {
                printf("%s: device type '%s' create option #%d: extensions not present\n",
                       devclass->gamedrv->name, device_typename(devtype), i);
                error = 1;
            }
        }
    }

    /* is there a custom validity check? */
    validity_check = (int (*)(const device_class *)) device_get_info_fct(devclass, DEVINFO_PTR_VALIDITY_CHECK);
    if (validity_check)
    {
        if (validity_check(devclass))
            error = 1;
    }

    return error;
}