Example #1
0
void rom_load_manager::process_disk_entries(const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag)
{
	/* loop until we hit the end of this region */
	for ( ; !ROMENTRY_ISREGIONEND(romp); romp++)
	{
		/* handle files */
		if (ROMENTRY_ISFILE(romp))
		{
			auto chd = std::make_unique<open_chd>(regiontag);

			hash_collection hashes(ROM_GETHASHDATA(romp));
			chd_error err;

			/* make the filename of the source */
			std::string filename = std::string(ROM_GETNAME(romp)).append(".chd");

			/* first open the source drive */
			LOG(("Opening disk image: %s\n", filename.c_str()));
			err = chd_error(open_disk_image(machine().options(), &machine().system(), romp, chd->orig_chd(), locationtag));
			if (err != CHDERR_NONE)
			{
				handle_missing_file(romp, std::string(), err);
				chd = nullptr;
				continue;
			}

			/* get the header and extract the SHA1 */
			hash_collection acthashes;
			acthashes.add_sha1(chd->orig_chd().sha1());

			/* verify the hash */
			if (hashes != acthashes)
			{
				strcatprintf(m_errorstring, "%s WRONG CHECKSUMS:\n", filename.c_str());
				dump_wrong_and_correct_checksums(hashes, acthashes);
				m_warnings++;
			}
			else if (hashes.flag(hash_collection::FLAG_BAD_DUMP))
			{
				strcatprintf(m_errorstring, "%s CHD NEEDS REDUMP\n", filename.c_str());
				m_knownbad++;
			}

			/* if not read-only, make the diff file */
			if (!DISK_ISREADONLY(romp))
			{
				/* try to open or create the diff */
				err = open_disk_diff(machine().options(), romp, chd->orig_chd(), chd->diff_chd());
				if (err != CHDERR_NONE)
				{
					strcatprintf(m_errorstring, "%s DIFF CHD ERROR: %s\n", filename.c_str(), chd_file::error_string(err));
					m_errors++;
					chd = nullptr;
					continue;
				}
			}

			/* we're okay, add to the list of disks */
			LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp)));
			m_chd_list.push_back(std::move(chd));
		}
	}
}
Example #2
0
static void process_disk_entries(romload_private *romdata, const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag)
{
	/* loop until we hit the end of this region */
	for ( ; !ROMENTRY_ISREGIONEND(romp); romp++)
	{
		/* handle files */
		if (ROMENTRY_ISFILE(romp))
		{
			open_chd *chd = global_alloc(open_chd(regiontag));

			hash_collection hashes(ROM_GETHASHDATA(romp));
			chd_error err;

			/* make the filename of the source */
			astring filename(ROM_GETNAME(romp), ".chd");

			/* first open the source drive */
			LOG(("Opening disk image: %s\n", filename.cstr()));
			err = chd_error(open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, chd->orig_chd(), locationtag));
			if (err != CHDERR_NONE)
			{
				handle_missing_file(romdata, romp, astring(), err);
				global_free(chd);
				continue;
			}

			/* get the header and extract the SHA1 */
			hash_collection acthashes;
			acthashes.add_sha1(chd->orig_chd().sha1());

			/* verify the hash */
			if (hashes != acthashes)
			{
				romdata->errorstring.catprintf("%s WRONG CHECKSUMS:\n", filename.cstr());
				dump_wrong_and_correct_checksums(romdata, hashes, acthashes);
				romdata->warnings++;
			}
			else if (hashes.flag(hash_collection::FLAG_BAD_DUMP))
			{
				romdata->errorstring.catprintf("%s CHD NEEDS REDUMP\n", filename.cstr());
				romdata->knownbad++;
			}

			/* if not read-only, make the diff file */
			if (!DISK_ISREADONLY(romp))
			{
				/* try to open or create the diff */
				err = open_disk_diff(romdata->machine().options(), romp, chd->orig_chd(), chd->diff_chd());
				if (err != CHDERR_NONE)
				{
					romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err));
					romdata->errors++;
					global_free(chd);
					continue;
				}
			}

			/* we're okay, add to the list of disks */
			LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp)));
			romdata->machine().romload_data->chd_list.append(*chd);
		}
	}
}
Example #3
0
static void print_game_rom(FILE *out, const game_driver *game, const machine_config *config)
{
	const game_driver *clone_of = driver_get_clone(game);
	int rom_type;
	machine_config *pconfig = (clone_of != NULL) ? machine_config_alloc(clone_of->machine_config) : NULL;

	/* iterate over 3 different ROM "types": BIOS, ROMs, DISKs */
	for (rom_type = 0; rom_type < 3; rom_type++)
	{
		const rom_source *source;
		const rom_entry *region;

		/* iterate over ROM sources: first the game, then any devices */
		for (source = rom_first_source(game, config); source != NULL; source = rom_next_source(game, config, source))
			for (region = rom_first_region(game, source); region != NULL; region = rom_next_region(region))
			{
				int is_disk = ROMREGION_ISDISKDATA(region);
				const rom_entry *rom;

				/* disk regions only work for disks */
				if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2))
					continue;

				/* iterate through ROM entries */
				for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
				{
					int is_bios = ROM_GETBIOSFLAGS(rom);
					const char *name = ROM_GETNAME(rom);
					int offset = ROM_GETOFFSET(rom);
					const rom_entry *parent_rom = NULL;
					char bios_name[100];

					/* BIOS ROMs only apply to bioses */
					if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0))
						continue;

					/* if we have a valid ROM and we are a clone, see if we can find the parent ROM */
					if (!ROM_NOGOODDUMP(rom) && clone_of != NULL)
					{
						const rom_source *psource;
						const rom_entry *pregion, *prom;

						/* scan the clone_of ROM for a matching ROM entry */
						for (psource = rom_first_source(clone_of, pconfig); psource != NULL; psource = rom_next_source(clone_of, pconfig, psource))
							for (pregion = rom_first_region(clone_of, psource); pregion != NULL; pregion = rom_next_region(pregion))
								for (prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom))
									if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0))
									{
										parent_rom = prom;
										break;
									}
					}

					/* scan for a BIOS name */
					bios_name[0] = 0;
					if (!is_disk && is_bios)
					{
						const rom_entry *brom;

						/* scan backwards through the ROM entries */
						for (brom = rom - 1; brom != game->rom; brom--)
							if (ROMENTRY_ISSYSTEM_BIOS(brom))
							{
								strcpy(bios_name, ROM_GETNAME(brom));
								break;
							}
					}

					/* opening tag */
					if (!is_disk)
						fprintf(out, "\t\t<rom");
					else
						fprintf(out, "\t\t<disk");

					/* add name, merge, bios, and size tags */
					if (name != NULL && name[0] != 0)
						fprintf(out, " name=\"%s\"", xml_normalize_string(name));
					if (parent_rom != NULL)
						fprintf(out, " merge=\"%s\"", xml_normalize_string(ROM_GETNAME(parent_rom)));
					if (bios_name[0] != 0)
						fprintf(out, " bios=\"%s\"", xml_normalize_string(bios_name));
					if (!is_disk)
						fprintf(out, " size=\"%d\"", rom_file_size(rom));

					/* dump checksum information only if there is a known dump */
					if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP))
					{
						char checksum[HASH_BUF_SIZE];
						int hashtype;

						/* iterate over hash function types and print out their values */
						for (hashtype = 0; hashtype < HASH_NUM_FUNCTIONS; hashtype++)
							if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), 1 << hashtype, checksum))
								fprintf(out, " %s=\"%s\"", hash_function_name(1 << hashtype), checksum);
					}

					/* append a region name */
					fprintf(out, " region=\"%s\"", ROMREGION_GETTAG(region));

					/* add nodump/baddump flags */
					if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP))
						fprintf(out, " status=\"nodump\"");
					if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP))
						fprintf(out, " status=\"baddump\"");

					/* for non-disk entries, print offset */
					if (!is_disk)
						fprintf(out, " offset=\"%x\"", offset);
					/* for disk entries, add the disk index */
					else
						fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom));

					/* add optional flag */
					if ((!is_disk && ROM_ISOPTIONAL(rom)) || (is_disk && DISK_ISOPTIONAL(rom)))
						fprintf(out, " optional=\"yes\"");

					fprintf(out, "/>\n");
				}
			}
	}

	if (pconfig != NULL)
		machine_config_free(pconfig);
}
Example #4
0
void info_xml_creator::output_rom(device_t &device)
{
	// iterate over 3 different ROM "types": BIOS, ROMs, DISKs
	for (int rom_type = 0; rom_type < 3; rom_type++)
		for (const rom_entry *region = rom_first_region(device); region != NULL; region = rom_next_region(region))
		{
			bool is_disk = ROMREGION_ISDISKDATA(region);

			// disk regions only work for disks
			if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2))
				continue;

			// iterate through ROM entries
			for (const rom_entry *rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
			{
				bool is_bios = ROM_GETBIOSFLAGS(rom);
				const char *name = ROM_GETNAME(rom);
				int offset = ROM_GETOFFSET(rom);
				const char *merge_name = NULL;
				char bios_name[100];

				// BIOS ROMs only apply to bioses
				if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0))
					continue;

				// if we have a valid ROM and we are a clone, see if we can find the parent ROM
				hash_collection hashes(ROM_GETHASHDATA(rom));
				if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
					merge_name = get_merge_name(hashes);
				if (&device != &m_drivlist.config().root_device())
					merge_name = NULL;
				// scan for a BIOS name
				bios_name[0] = 0;
				if (!is_disk && is_bios)
				{
					// scan backwards through the ROM entries
					for (const rom_entry *brom = rom - 1; brom != m_drivlist.driver().rom; brom--)
						if (ROMENTRY_ISSYSTEM_BIOS(brom))
						{
							strcpy(bios_name, ROM_GETNAME(brom));
							break;
						}
				}

				astring output;

				// opening tag
				if (!is_disk)
					output.cat("\t\t<rom");
				else
					output.cat("\t\t<disk");

				// add name, merge, bios, and size tags */
				if (name != NULL && name[0] != 0)
					output.catprintf(" name=\"%s\"", xml_normalize_string(name));
				if (merge_name != NULL)
					output.catprintf(" merge=\"%s\"", xml_normalize_string(merge_name));
				if (bios_name[0] != 0)
					output.catprintf(" bios=\"%s\"", xml_normalize_string(bios_name));
				if (!is_disk)
					output.catprintf(" size=\"%d\"", rom_file_size(rom));

				// dump checksum information only if there is a known dump
				if (!hashes.flag(hash_collection::FLAG_NO_DUMP))
				{
					// iterate over hash function types and print m_output their values
					astring tempstr;
					output.catprintf(" %s", hashes.attribute_string(tempstr));
				}
				else
					output.cat(" status=\"nodump\"");

				// append a region name
				output.catprintf(" region=\"%s\"", ROMREGION_GETTAG(region));

				// for non-disk entries, print offset
				if (!is_disk)
					output.catprintf(" offset=\"%x\"", offset);

				// for disk entries, add the disk index
				else
				{
					output.catprintf(" index=\"%x\"", DISK_GETINDEX(rom));
					output.catprintf(" writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes");
				}

				// add optional flag
				if (ROM_ISOPTIONAL(rom))
					output.cat(" optional=\"yes\"");

				output.cat("/>\n");

				fprintf(m_output, "%s", output.cstr());
			}
		}
}
Example #5
0
static int process_disk_entries(struct rom_load_data *romdata, const struct RomModule *romp)
{
	/* loop until we hit the end of this region */
	while (!ROMENTRY_ISREGIONEND(romp))
	{
		/* handle files */
		if (ROMENTRY_ISFILE(romp))
		{
			struct chd_file *source, *diff = NULL;
			struct chd_header header;
			char filename[1024], *c;
			char acthash[HASH_BUF_SIZE];
			int err;

			/* make the filename of the source */
			strcpy(filename, ROM_GETNAME(romp));
			c = strrchr(filename, '.');
			if (c)
				strcpy(c, ".chd");
			else
				strcat(filename, ".chd");

			/* first open the source drive */
			debugload("Opening disk image: %s\n", filename);
			source = chd_open(filename, 0, NULL);
			if (!source)
			{
				if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
					sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename);
				else
					sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s NOT FOUND\n", filename);
				romdata->errors++;
				romp++;
				continue;
			}

			/* get the header and extract the MD5/SHA1 */
			header = *chd_get_header(source);
			hash_data_clear(acthash);
			hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5);
			hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1);

			/* verify the MD5 */
			if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0))
			{
				sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s WRONG CHECKSUMS:\n", filename);
				dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash);
				romdata->warnings++;
			}

			/* if not read-only, make the diff file */
			if (!DISK_ISREADONLY(romp))
			{
				/* make the filename of the diff */
				strcpy(filename, ROM_GETNAME(romp));
				c = strrchr(filename, '.');
				if (c)
					strcpy(c, ".dif");
				else
					strcat(filename, ".dif");

				/* try to open the diff */
				debugload("Opening differencing image: %s\n", filename);
				diff = chd_open(filename, 1, source);
				if (!diff)
				{
					/* didn't work; try creating it instead */
					debugload("Creating differencing image: %s\n", filename);
					err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source);
					if (err != CHDERR_NONE)
					{
						if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename);
						else
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s: CAN'T CREATE DIFF FILE\n", filename);
						romdata->errors++;
						romp++;
						continue;
					}

					/* open the newly-created diff file */
					debugload("Opening differencing image: %s\n", filename);
					diff = chd_open(filename, 1, source);
					if (!diff)
					{
						if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s UNSUPPORTED CHD VERSION\n", filename);
						else
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s: CAN'T OPEN DIFF FILE\n", filename);
						romdata->errors++;
						romp++;
						continue;
					}
				}
			}

			/* we're okay, set the handle */
			debugload("Assigning to handle %d\n", DISK_GETINDEX(romp));
			disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff;
			romp++;
		}
	}
	return 1;
}
Example #6
0
static void process_disk_entries(rom_load_data *romdata, const rom_entry *romp)
{
	/* loop until we hit the end of this region */
	while (!ROMENTRY_ISREGIONEND(romp))
	{
		/* handle files */
		if (ROMENTRY_ISFILE(romp))
		{
			chd_file *source, *diff = NULL;
			chd_header header;
			char filename[1024];
			char acthash[HASH_BUF_SIZE];
			chd_error err;

			/* make the filename of the source */
			sprintf(filename, "%s.chd", ROM_GETNAME(romp));

			/* first open the source drive */
			debugload("Opening disk image: %s\n", filename);
			err = open_disk_image(Machine->gamedrv, romp, &source);
			if (err != CHDERR_NONE)
			{
				if (err == CHDERR_UNSUPPORTED_VERSION)
					sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename);
				else
					sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s NOT FOUND\n", filename);

				/* if this is NO_DUMP, keep going, though the system may not be able to handle it */
				if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_NO_DUMP))
					romdata->warnings++;
				else
					romdata->errors++;
				romp++;
				continue;
			}

			/* get the header and extract the MD5/SHA1 */
			header = *chd_get_header(source);
			hash_data_clear(acthash);
			hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5);
			hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1);

			/* verify the MD5 */
			if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0))
			{
				sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s WRONG CHECKSUMS:\n", filename);
				dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash);
				romdata->warnings++;
			}
			else if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_BAD_DUMP))
			{
				sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s CHD NEEDS REDUMP\n", filename);
				romdata->warnings++;
			}

			/* if not read-only, make the diff file */
			if (!DISK_ISREADONLY(romp))
			{
				/* make the filename of the diff */
				sprintf(filename, "%s.dif", ROM_GETNAME(romp));

				/* try to open the diff */
				debugload("Opening differencing image: %s\n", filename);
				err = chd_open(filename, CHD_OPEN_READWRITE, source, &diff);
				if (err != CHDERR_NONE)
				{
					/* didn't work; try creating it instead */
					debugload("Creating differencing image: %s\n", filename);
					err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source);
					if (err != CHDERR_NONE)
					{
						if (err == CHDERR_UNSUPPORTED_VERSION)
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename);
						else
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s: CAN'T CREATE DIFF FILE\n", filename);
						romdata->errors++;
						romp++;
						continue;
					}

					/* open the newly-created diff file */
					debugload("Opening differencing image: %s\n", filename);
					err = chd_open(filename, CHD_OPEN_READWRITE, source, &diff);
					if (err != CHDERR_NONE)
					{
						if (err == CHDERR_UNSUPPORTED_VERSION)
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s UNSUPPORTED CHD VERSION\n", filename);
						else
							sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s: CAN'T OPEN DIFF FILE\n", filename);
						romdata->errors++;
						romp++;
						continue;
					}
				}
			}

			/* we're okay, set the handle */
			debugload("Assigning to handle %d\n", DISK_GETINDEX(romp));
			disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff;
			romp++;
		}
	}
}
Example #7
0
static void print_game_rom(FILE* out, const game_driver* game)
{
	const rom_entry *region, *rom, *chunk;
	const rom_entry *pregion, *prom, *fprom=NULL;
	const game_driver *clone_of;

	if (!game->rom)
		return;

	clone_of = driver_get_clone(game);
	for (region = rom_first_region(game); region; region = rom_next_region(region))
		for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
		{
			int offset, length, in_parent, is_disk, is_bios, found_bios, i;
			char name[100], bios_name[100];

			strcpy(name,ROM_GETNAME(rom));
			offset = ROM_GETOFFSET(rom);
			is_disk = ROMREGION_ISDISKDATA(region);
			is_bios = ROM_GETBIOSFLAGS(rom);

			in_parent = 0;
			length = 0;
			for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk))
				length += ROM_GETLENGTH(chunk);

			if (!ROM_NOGOODDUMP(rom) && clone_of)
			{
				fprom=NULL;
				for (pregion = rom_first_region(clone_of); pregion; pregion = rom_next_region(pregion))
					for (prom = rom_first_file(pregion); prom; prom = rom_next_file(prom))
						if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0))
						{
							if (!fprom || !strcmp(ROM_GETNAME(prom), name))
								fprom=prom;
							in_parent = 1;
						}
			}

			found_bios = 0;
			if(!is_disk && is_bios && game->bios)
			{
				const bios_entry *thisbios = game->bios;

				/* Match against bios short names */
				while(!found_bios && !BIOSENTRY_ISEND(thisbios) )
				{
					if((is_bios-1) == thisbios->value) /* Note '-1' */
					{
						strcpy(bios_name,thisbios->_name);
						found_bios = 1;
					}

					thisbios++;
				}
			}


			if (!is_disk)
				fprintf(out, "\t\t<rom");
			else
				fprintf(out, "\t\t<disk");

			if (*name)
				fprintf(out, " name=\"%s\"", normalize_string(name));
			if (in_parent)
				fprintf(out, " merge=\"%s\"", normalize_string(ROM_GETNAME(fprom)));
			if (!is_disk && found_bios)
				fprintf(out, " bios=\"%s\"", normalize_string(bios_name));
			if (!is_disk)
				fprintf(out, " size=\"%d\"", length);

			/* dump checksum information only if there is a known dump */
			if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP))
			{
				for (i=0;i<HASH_NUM_FUNCTIONS;i++)
				{
					int func = 1<<i;
					const char* func_name = hash_function_name(func);
					char checksum[1000];

					if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), func, checksum))
					{
						fprintf(out, " %s=\"%s\"", func_name, checksum);
					}
				}
			}

			switch (ROMREGION_GETTYPE(region))
			{
				case REGION_CPU1: fprintf(out, " region=\"cpu1\""); break;
				case REGION_CPU2: fprintf(out, " region=\"cpu2\""); break;
				case REGION_CPU3: fprintf(out, " region=\"cpu3\""); break;
				case REGION_CPU4: fprintf(out, " region=\"cpu4\""); break;
				case REGION_CPU5: fprintf(out, " region=\"cpu5\""); break;
				case REGION_CPU6: fprintf(out, " region=\"cpu6\""); break;
				case REGION_CPU7: fprintf(out, " region=\"cpu7\""); break;
				case REGION_CPU8: fprintf(out, " region=\"cpu8\""); break;
				case REGION_GFX1: fprintf(out, " region=\"gfx1\""); break;
				case REGION_GFX2: fprintf(out, " region=\"gfx2\""); break;
				case REGION_GFX3: fprintf(out, " region=\"gfx3\""); break;
				case REGION_GFX4: fprintf(out, " region=\"gfx4\""); break;
				case REGION_GFX5: fprintf(out, " region=\"gfx5\""); break;
				case REGION_GFX6: fprintf(out, " region=\"gfx6\""); break;
				case REGION_GFX7: fprintf(out, " region=\"gfx7\""); break;
				case REGION_GFX8: fprintf(out, " region=\"gfx8\""); break;
				case REGION_PROMS: fprintf(out, " region=\"proms\""); break;
				case REGION_SOUND1: fprintf(out, " region=\"sound1\""); break;
				case REGION_SOUND2: fprintf(out, " region=\"sound2\""); break;
				case REGION_SOUND3: fprintf(out, " region=\"sound3\""); break;
				case REGION_SOUND4: fprintf(out, " region=\"sound4\""); break;
				case REGION_SOUND5: fprintf(out, " region=\"sound5\""); break;
				case REGION_SOUND6: fprintf(out, " region=\"sound6\""); break;
				case REGION_SOUND7: fprintf(out, " region=\"sound7\""); break;
				case REGION_SOUND8: fprintf(out, " region=\"sound8\""); break;
				case REGION_USER1: fprintf(out, " region=\"user1\""); break;
				case REGION_USER2: fprintf(out, " region=\"user2\""); break;
				case REGION_USER3: fprintf(out, " region=\"user3\""); break;
				case REGION_USER4: fprintf(out, " region=\"user4\""); break;
				case REGION_USER5: fprintf(out, " region=\"user5\""); break;
				case REGION_USER6: fprintf(out, " region=\"user6\""); break;
				case REGION_USER7: fprintf(out, " region=\"user7\""); break;
				case REGION_USER8: fprintf(out, " region=\"user8\""); break;
				case REGION_DISKS: fprintf(out, " region=\"disks\""); break;
				default: fprintf(out, " region=\"0x%x\"", ROMREGION_GETTYPE(region));
		}

		if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP))
			fprintf(out, " status=\"nodump\"");
		if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP))
			fprintf(out, " status=\"baddump\"");

		if (!is_disk)
		{
			if (ROMREGION_GETFLAGS(region) & ROMREGION_DISPOSE)
				fprintf(out, " dispose=\"yes\"");

			fprintf(out, " offset=\"%x\"", offset);
			fprintf(out, "/>\n");
		}
		else
		{
			fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom));
			fprintf(out, "/>\n");
		}
	}
}