예제 #1
0
파일: rsdos.cpp 프로젝트: MASHinfo/mame
static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, const char *fname, const char *fork, imgtool::stream &sourcef, util::option_resolution *writeoptions)
{
	floperr_t ferr;
	imgtoolerr_t err;
	imgtool::image &img(partition.image());
	struct rsdos_dirent ent, ent2;
	size_t i;
	uint64_t sz;
	uint64_t freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	uint8_t granule_count;
	uint8_t granule_map[MAX_GRANULEMAP_SIZE];

	// can we write to this image?
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	err = rsdos_diskimage_freespace(partition, &freespace);
	if (err)
		return err;

	// is there enough space?
	sz = sourcef.size();
	if (sz > freespace)
		return IMGTOOLERR_NOSPACE;

	// setup our directory entry
	err = prepare_dirent(ent, fname);
	if (err)
		return err;

	ent.ftype = writeoptions->lookup_int(RSDOS_OPTIONS_FTYPE);
	ent.asciiflag = uint8_t(writeoptions->lookup_int(RSDOS_OPTIONS_ASCII)) - 1;
	ent.lastsectorbytes_lsb = sz % 256;
	ent.lastsectorbytes_msb = (((sz % 256) == 0) && (sz > 0)) ? 1 : 0;
	gptr = &ent.first_granule;

	ferr = get_granule_map(img, granule_map, &granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	g = 0x00;

	do
	{
		while (granule_map[g] != 0xff)
		{
			g++;
			if ((g >= granule_count) || (g == 0))
				return IMGTOOLERR_UNEXPECTED;   // we should have already verified that there is enough space
		}
		*gptr = g;
		gptr = &granule_map[g];


		i = std::min(sz, uint64_t(9*256));
		err = transfer_to_granule(img, g, i, sourcef);
		if (err)
			return err;

		sz -= i;

		// go to next granule
		g++;
	}
	while(sz > 0);

	// now that we are done with the file, we need to specify the final entry
	// in the file allocation table
	*gptr = 0xc0 + ((i + 255) / 256);

	// now we need to find an empty directory entry
	i = -1;
	do
	{
		ferr = get_rsdos_dirent(img, ++i, ent2);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while((ent2.filename[0] != '\0') && strcmp(ent.filename, ent2.filename) && (ent2.filename[0] != -1));

	// delete file if it already exists
	if (ent2.filename[0] && (ent2.filename[0] != -1))
	{
		err = delete_entry(img, ent2, i);
		if (err)
			return err;
	}

	ferr = put_rsdos_dirent(img, i, ent);
	if (ferr)
		return imgtool_floppy_error(ferr);

	// write the granule map back out
	ferr = put_granule_map(img, granule_map, granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
예제 #2
0
파일: vzdos.c 프로젝트: cdenix/psmame
static imgtoolerr_t vzdos_writefile(imgtool_partition *partition, int offset, imgtool_stream *sourcef, vzdos_dirent *entry)
{
	imgtoolerr_t ret;
	imgtool_image *img = imgtool_partition_image(partition);
	int index, track, sector, toread, next_track, next_sector;
	vzdos_dirent temp_entry;
	UINT64 filesize = 0, freespace = 0;
	UINT8 buffer[DATA_SIZE + 2];
	char filename[9];

	/* is the image writeable? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	/* check for already existing filename -> overwrite */
	strcpy(filename, entry->fname);
	filename[vzdos_get_fname_len(entry->fname) + 1] = 0x00;
	ret = vzdos_get_dirent_fname(img, filename, &temp_entry);
	if (!ret) {
		/* file already exists, delete it */
		ret = vzdos_diskimage_deletefile(partition, filename);
		if (ret) return ret;
	} else if (ret != IMGTOOLERR_FILENOTFOUND) {
		/* another error occured, return it */
		return ret;
	}

	ret = (imgtoolerr_t)stream_seek(sourcef, offset, SEEK_SET);
	if (ret) return ret;

	/* check if there is enough space */
	filesize = stream_size(sourcef) - offset;

	ret = vzdos_diskimage_freespace(partition, &freespace);
	if (ret) return ret;

	if (filesize > freespace)
		return IMGTOOLERR_NOSPACE;

	/* get next free track and sector */
	ret = vzdos_free_trackmap(img, &track, &sector);
	if (ret) return ret;

	entry->end_address = entry->start_address + (unsigned int) filesize;
	entry->start_track   = track;
	entry->start_sector  = sector;

	/* search for next free directory entry */
	for (index = 0; index < MAX_DIRENTS; index++) {
		ret = vzdos_get_dirent(img, index, &temp_entry);
		if (ret == IMGTOOLERR_FILENOTFOUND)
			break;
		else if (ret)
			return (ret);
	}

	/* write directory entry to disk */
	ret = vzdos_set_dirent(img, index, *entry);
	if (ret) return ret;

	next_track  = 0;
	next_sector = 0;

	/* write data to disk */
	while (filesize > 0) {

		toread = filesize > DATA_SIZE ? DATA_SIZE : filesize;
		stream_read(sourcef, buffer, toread);

		filesize -= toread;

		/* mark sector as used */
		ret = vzdos_set_trackmap(img, track, sector);
		if (ret) return ret;

		/* get track and sector for next sector */
		if (filesize > 0) {
			ret = vzdos_free_trackmap(img, &next_track, &next_sector);
			if (ret) return ret;
		} else {
			next_track = 0;
			next_sector = 0;
		}
		buffer[DATA_SIZE]     = next_track;
		buffer[DATA_SIZE + 1] = next_sector;

		/* write sector to disk */
		ret = vzdos_write_sector_data(img, track, sector, buffer);
		if (ret) return ret;

		track  = next_track;
		sector = next_sector;
	}

	return IMGTOOLERR_SUCCESS;

}
예제 #3
0
파일: bml3.c 프로젝트: antervud/MAMEHub
static imgtoolerr_t bml3_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions)
{
	floperr_t ferr;
	imgtoolerr_t err;
	imgtool_image *img = imgtool_partition_image(partition);
	bml3_diskinfo *info = bml3_get_diskinfo(img);
	struct bml3_dirent ent, ent2;
	size_t i;
	UINT64 sz, read_sz;
	UINT64 freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	UINT8 granule_count;
	UINT8 granule_map[MAX_GRANULEMAP_SIZE];
	UINT8 eof_buf[MAX_SECTOR_SIZE];

	// one-time setup of eof_buf
	memset(eof_buf, 0, sizeof(eof_buf));
	eof_buf[0] = 0x1A;

	/* can we write to this image? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	err = bml3_diskimage_freespace(partition, &freespace);
	if (err)
		return err;

	/* is there enough space? */
	sz = read_sz = stream_size(sourcef);
	if (info->variant == 0) {
		// also need to write EOF
		sz++;
	}
	if (sz > freespace)
		return IMGTOOLERR_NOSPACE;

	/* setup our directory entry */
	err = prepare_dirent(info->variant, &ent, fname);
	if (err)
		return err;

	ent.ftype = option_resolution_lookup_int(writeoptions, BML3_OPTIONS_FTYPE);
	ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, BML3_OPTIONS_ASCII)) - 1;
	gptr = &ent.first_granule;

	ferr = get_granule_map(img, granule_map, &granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	g = 0x00;

	do
	{
		while (granule_map[g] != 0xff)
		{
			g++;
			if ((g >= granule_count) || (g == 0))
				return IMGTOOLERR_UNEXPECTED;   /* We should have already verified that there is enough space */
		}
		*gptr = g;
		gptr = &granule_map[g];


		i = MIN(read_sz, info->granule_sectors * info->sector_size);
		if (i > 0) {
			err = transfer_to_granule(img, g, i, sourcef);
			if (err)
				return err;
			read_sz -= i;
			sz -= i;
		}
		if (i < info->granule_sectors * info->sector_size && sz > 0) {
			// write EOF and trailing NULs in the final sector
			ferr = write_granule(img, g, i, (info->granule_sectors * info->sector_size - i - 1) % info->sector_size + 1, eof_buf);
			if (ferr)
				return imgtool_floppy_error(ferr);
			sz--;
			i++;
		}

		/* Go to next granule */
		g++;
	}
	while(sz > 0);

	/* Now that we are done with the file, we need to specify the final entry
	 * in the file allocation table
	 */
	*gptr = 0xc0 + ((i + info->sector_size-1) / info->sector_size) - (info->variant == 0 ? 1 : 0);
	ent.lastsectorbytes = (i - 1) % info->sector_size + 1;

	/* delete file if it already exists */
	err = bml3_diskimage_deletefile(partition, fname);
	if (err && err != IMGTOOLERR_FILENOTFOUND)
		return err;

	/* Now we need to find an empty directory entry */
	i = -1;
	do
	{
		ferr = get_bml3_dirent(img, ++i, &ent2);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while(ent2.fname[0] != '\0' && ent2.fname[0] != -1);

	ferr = put_bml3_dirent(img, i, &ent);
	if (ferr)
		return imgtool_floppy_error(ferr);

	/* write the granule map back out */
	ferr = put_granule_map(img, granule_map, granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
예제 #4
0
파일: rsdos.c 프로젝트: coinhelper/jsmess
static imgtoolerr_t rsdos_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions)
{
	floperr_t ferr;
	imgtoolerr_t err;
	imgtool_image *img = imgtool_partition_image(partition);
	struct rsdos_dirent ent, ent2;
	size_t i;
	UINT64 sz;
	UINT64 freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	UINT8 granule_count;
	UINT8 granule_map[MAX_GRANULEMAP_SIZE];

	/* can we write to this image? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	err = rsdos_diskimage_freespace(partition, &freespace);
	if (err)
		return err;

	/* is there enough space? */
	sz = stream_size(sourcef);
	if (sz > freespace)
		return IMGTOOLERR_NOSPACE;

	/* setup our directory entry */
	err = prepare_dirent(&ent, fname);
	if (err)
		return err;

	ent.ftype = option_resolution_lookup_int(writeoptions, RSDOS_OPTIONS_FTYPE);
	ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, RSDOS_OPTIONS_ASCII)) - 1;
	ent.lastsectorbytes_lsb = sz % 256;
	ent.lastsectorbytes_msb = (((sz % 256) == 0) && (sz > 0)) ? 1 : 0;
	gptr = &ent.first_granule;

	ferr = get_granule_map(img, granule_map, &granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	g = 0x00;

	do
	{
		while (granule_map[g] != 0xff)
		{
			g++;
			if ((g >= granule_count) || (g == 0))
				return IMGTOOLERR_UNEXPECTED;	/* We should have already verified that there is enough space */
		}
		*gptr = g;
		gptr = &granule_map[g];


		i = MIN(sz, (9*256));
		err = transfer_to_granule(img, g, i, sourcef);
		if (err)
			return err;

		sz -= i;

		/* Go to next granule */
		g++;
	}
	while(sz > 0);

	/* Now that we are done with the file, we need to specify the final entry
     * in the file allocation table
     */
	*gptr = 0xc0 + ((i + 255) / 256);

	/* Now we need to find an empty directory entry */
	i = -1;
	do
	{
		ferr = get_rsdos_dirent(img, ++i, &ent2);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while((ent2.fname[0] != '\0') && strcmp(ent.fname, ent2.fname) && (ent2.fname[0] != -1));

	/* delete file if it already exists */
	if (ent2.fname[0] && (ent2.fname[0] != -1))
	{
		err = delete_entry(img, &ent2, i);
		if (err)
			return err;
	}

	ferr = put_rsdos_dirent(img, i, &ent);
	if (ferr)
		return imgtool_floppy_error(ferr);

	/* write the granule map back out */
	ferr = put_granule_map(img, granule_map, granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}