コード例 #1
0
ファイル: g64_dsk.c プロジェクト: gbraad/mame
bool g64_format::save(io_generic *io, floppy_image *image)
{
	int tracks, heads;
	image->get_actual_geometry(tracks, heads);
	tracks = TRACK_COUNT * heads;

	// write header
	UINT8 header[] = { 'G', 'C', 'R', '-', '1', '5', '4', '1', 0x00, tracks, TRACK_LENGTH & 0xff, TRACK_LENGTH >> 8 };
	io_generic_write(io, header, POS_SIGNATURE, sizeof(header));

	// write tracks
	for (int head = 0; head < heads; head++) {
		int tracks_written = 0;

		dynamic_buffer trackbuf(TRACK_LENGTH-2);

		for (int track = 0; track < TRACK_COUNT; track++) {
			UINT32 tpos = POS_TRACK_OFFSET + (track * 4);
			UINT32 spos = tpos + (tracks * 4);
			UINT32 dpos = POS_TRACK_OFFSET + (tracks * 4 * 2) + (tracks_written * TRACK_LENGTH);

			io_generic_write_filler(io, 0x00, tpos, 4);
			io_generic_write_filler(io, 0x00, spos, 4);

			if (image->get_buffer(track, head).size() <= 1)
				continue;

			int track_size;
			int speed_zone;

			// figure out the cell size and speed zone from the track data
			if ((speed_zone = generate_bitstream(track, head, 3, &trackbuf[0], track_size, image)) == -1)
				if ((speed_zone = generate_bitstream(track, head, 2, &trackbuf[0], track_size, image)) == -1)
					if ((speed_zone = generate_bitstream(track, head, 1, &trackbuf[0], track_size, image)) == -1)
						if ((speed_zone = generate_bitstream(track, head, 0, &trackbuf[0], track_size, image)) == -1)
							throw emu_fatalerror("g64_format: Cannot determine speed zone for track %u", track);

			LOG_FORMATS("head %u track %u size %u cell %u\n", head, track, track_size, c1541_cell_size[speed_zone]);

			UINT8 track_offset[4];
			UINT8 speed_offset[4];
			UINT8 track_length[2];

			place_integer_le(track_offset, 0, 4, dpos);
			place_integer_le(speed_offset, 0, 4, speed_zone);
			place_integer_le(track_length, 0, 2, track_size/8);

			io_generic_write(io, track_offset, tpos, 4);
			io_generic_write(io, speed_offset, spos, 4);
			io_generic_write_filler(io, 0xff, dpos, TRACK_LENGTH);
			io_generic_write(io, track_length, dpos, 2);
			io_generic_write(io, &trackbuf[0], dpos + 2, track_size);

			tracks_written++;
		}
	}

	return true;
}
コード例 #2
0
bool mfi_format::save(io_generic *io, floppy_image *image)
{
	int tracks, heads;
	image->get_actual_geometry(tracks, heads);
	int max_track_size = 0;
	for(int track=0; track<tracks; track++)
		for(int head=0; head<heads; head++) {
			int tsize = image->get_track_size(track, head);
			if(tsize > max_track_size)
				 max_track_size = tsize;
		}

	header h;
	entry entries[84*2];
	memcpy(h.sign, sign, 16);
	h.cyl_count = tracks;
	h.head_count = heads;

	io_generic_write(io, &h, 0, sizeof(header));

	memset(entries, 0, sizeof(entries));

	int pos = sizeof(header) + tracks*heads*sizeof(entry);
	int epos = 0;
	UINT32 *precomp = global_alloc_array(UINT32, max_track_size);
	UINT8 *postcomp = global_alloc_array(UINT8, max_track_size*4 + 1000);

	for(int track=0; track<tracks; track++)
		for(int head=0; head<heads; head++) {
			int tsize = image->get_track_size(track, head);
			if(!tsize) {
				epos++;
				continue;
			}

			memcpy(precomp, image->get_buffer(track, head), tsize*4);
			for(int j=0; j<tsize-1; j++)
				precomp[j] = (precomp[j] & floppy_image::MG_MASK) |
					((precomp[j+1] & floppy_image::TIME_MASK) -
					 (precomp[j] & floppy_image::TIME_MASK));
			precomp[tsize-1] = (precomp[tsize-1] & floppy_image::MG_MASK) |
				(200000000 - (precomp[tsize-1] & floppy_image::TIME_MASK));

			uLongf csize = max_track_size*4 + 1000;
			if(compress(postcomp, &csize, (const Bytef *)precomp, tsize*4) != Z_OK)
				return false;

			entries[epos].offset = pos;
			entries[epos].uncompressed_size = tsize*4;
			entries[epos].compressed_size = csize;
			epos++;

			io_generic_write(io, postcomp, pos, csize);
			pos += csize;
		}

	io_generic_write(io, entries, sizeof(header), tracks*heads*sizeof(entry));
	return true;
}
コード例 #3
0
ファイル: g64_dsk.c プロジェクト: tweakoz/vindigo
bool g64_format::save(io_generic *io, floppy_image *image)
{
	UINT8 header[] = { 'G', 'C', 'R', '-', '1', '5', '4', '1', 0x00, 0x54, TRACK_LENGTH & 0xff, TRACK_LENGTH >> 8 };

	io_generic_write(io, header, SIGNATURE, sizeof(header));
	
	int head = 0;
	int tracks_written = 0;

	for (int track = 0; track < 84; track++) {
		offs_t tpos = TRACK_OFFSET + track * 4;
		offs_t spos = SPEED_ZONE + track * 4;
		offs_t dpos = TRACK_DATA + tracks_written * TRACK_LENGTH;

		io_generic_write_filler(io, 0x00, tpos, 4);
		io_generic_write_filler(io, 0x00, spos, 4);

		if (image->get_track_size(track, head) <= 1)
			continue;

		UINT8 *trackbuf = global_alloc_array(UINT8, TRACK_LENGTH-2);
		int track_size;
		int speed_zone;

		// figure out the cell size and speed zone from the track data
		if ((speed_zone = generate_bitstream(track, head, 3, trackbuf, track_size, image)) == -1)
			if ((speed_zone = generate_bitstream(track, head, 2, trackbuf, track_size, image)) == -1)
				if ((speed_zone = generate_bitstream(track, head, 1, trackbuf, track_size, image)) == -1)
					if ((speed_zone = generate_bitstream(track, head, 0, trackbuf, track_size, image)) == -1)
						throw emu_fatalerror("g64_format: Cannot determine speed zone for track %u", track);

		LOG_FORMATS("track %u size %u cell %u\n", track, track_size, c1541_cell_size[speed_zone]);

		UINT8 track_offset[4];
		UINT8 speed_offset[4];
		UINT8 track_length[2];

		place_integer_le(track_offset, 0, 4, dpos);
		place_integer_le(speed_offset, 0, 4, speed_zone);
		place_integer_le(track_length, 0, 2, track_size/8);

		io_generic_write(io, track_offset, tpos, 4);
		io_generic_write(io, speed_offset, spos, 4);
		io_generic_write_filler(io, 0xff, dpos, TRACK_LENGTH);
		io_generic_write(io, track_length, dpos, 2);
		io_generic_write(io, trackbuf, dpos + 2, track_size);
		
		tracks_written++;

		global_free(trackbuf);
	}

	return true;
}
コード例 #4
0
ファイル: vdk_dsk.cpp プロジェクト: MASHinfo/mame
bool vdk_format::save(io_generic *io, floppy_image *image)
{
	uint8_t bitstream[500000/8];
	uint8_t sector_data[50000];
	desc_xs sectors[256];
	uint64_t file_offset = 0;

	int track_count, head_count;
	image->get_actual_geometry(track_count, head_count);

	// write header
	uint8_t header[12];

	header[0] = 'd';
	header[1] = 'k';
	header[2] = sizeof(header) % 0x100;
	header[3] = sizeof(header) / 0x100;
	header[4] = 0x10;
	header[5] = 0x10;
	header[6] = 'M';
	header[7] = 0x01;
	header[8] = track_count;
	header[9] = head_count;
	header[10] = 0;
	header[11] = 0;

	io_generic_write(io, header, file_offset, sizeof(header));
	file_offset += sizeof(header);

	// write disk data
	for (int track = 0; track < track_count; track++)
	{
		for (int head = 0; head < head_count; head++)
		{
			int track_size;
			generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image);
			extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data));

			for (int i = 0; i < SECTOR_COUNT; i++)
			{
				io_generic_write(io, sectors[FIRST_SECTOR_ID + i].data, file_offset, SECTOR_SIZE);
				file_offset += SECTOR_SIZE;
			}
		}
	}

	return true;
}
コード例 #5
0
ファイル: esq16_dsk.c プロジェクト: CJBass/mame2013-libretro
bool esqimg_format::save(io_generic *io, floppy_image *image)
{
	int track_count, head_count, sector_count;
	get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);

	if(track_count != 80)
		track_count = 80;

	// Happens for a fully unformatted floppy
	if(!head_count)
		head_count = 2;

	if(sector_count != 10)
		sector_count = 10;

	UINT8 sectdata[11*512];
	int track_size = sector_count*512;

	for(int track=0; track < track_count; track++) {
		for(int head=0; head < head_count; head++) {
			get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
			io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
		}
	}

	return true;
}
コード例 #6
0
ファイル: st_dsk.cpp プロジェクト: MASHinfo/mame
bool st_format::save(io_generic *io, floppy_image *image)
{
	int track_count, head_count, sector_count;
	get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);

	if(track_count < 80)
		track_count = 80;
	else if(track_count > 82)
		track_count = 82;

	// Happens for a fully unformatted floppy
	if(!head_count)
		head_count = 1;

	if(sector_count > 11)
		sector_count = 11;
	else if(sector_count < 9)
		sector_count = 9;

	uint8_t sectdata[11*512];
	int track_size = sector_count*512;

	for(int track=0; track < track_count; track++) {
		for(int head=0; head < head_count; head++) {
			get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
			io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
		}
	}

	return true;
}
コード例 #7
0
ファイル: hxcmfm_dsk.c プロジェクト: BrandoCommando/mame
bool mfm_format::save(io_generic *io, floppy_image *image)
{
	// TODO: HD support
	MFMIMG header;
	int track_count, head_count;
	image->get_actual_geometry(track_count, head_count);

	memcpy(&header.headername, MFM_FORMAT_HEADER, 7);
	header.number_of_track = track_count;
	header.number_of_side = head_count;
	header.floppyRPM = 0;
	header.floppyBitRate = 250;
	header.floppyiftype = 4;
	header.mfmtracklistoffset = sizeof(MFMIMG);

	io_generic_write(io, &header, 0, sizeof(MFMIMG));

	int tpos = sizeof(MFMIMG);
	int dpos = tpos + track_count*head_count*sizeof(MFMTRACKIMG);

	UINT8 trackbuf[150000/8];

	for(int track=0; track < track_count; track++) {
		for(int side=0; side < head_count; side++) {
			int track_size;
			generate_bitstream_from_track(track, side, 2000, trackbuf, track_size, image);
			track_size = (track_size+7)/8;

			MFMTRACKIMG trackdesc;
			trackdesc.track_number = track;
			trackdesc.side_number = side;
			trackdesc.mfmtracksize = track_size;
			trackdesc.mfmtrackoffset = dpos;

			io_generic_write(io, &trackdesc, tpos, sizeof(MFMTRACKIMG));
			io_generic_write(io, trackbuf, dpos, track_size);

			tpos += sizeof(MFMTRACKIMG);
			dpos += track_size;
		}
	}

	return true;
}
コード例 #8
0
ファイル: jvc_dsk.c プロジェクト: Fulg/mame
bool jvc_format::save(io_generic *io, floppy_image *image)
{
	UINT8 bitstream[500000/8];
	UINT8 sector_data[50000];
	desc_xs sectors[256];
	UINT64 file_offset = 0;

	int track_count, head_count;
	image->get_actual_geometry(track_count, head_count);

	// we'll write a header if the disk is two-sided
	if (head_count == 2)
	{
		UINT8 header[2];
		header[0] = 18;
		header[1] = 2;
		io_generic_write(io, header, file_offset, sizeof(header));
		file_offset += sizeof(header);
	}

	// write disk data
	for (int track = 0; track < track_count; track++)
	{
		for (int head = 0; head < head_count; head++)
		{
			int track_size;
			generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image);
			extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data));

			for (int i = 0; i < 18; i++)
			{
				if (sectors[1 + i].size != 256)
					emu_fatalerror("jvc_format: invalid sector size: %d\n", sectors[1 + i].size);

				io_generic_write(io, sectors[1 + i].data, file_offset, sectors[1 + i].size);
				file_offset += sectors[1 + i].size;
			}
		}
	}

	return true;
}
コード例 #9
0
ファイル: ioprocs.c プロジェクト: curtiszimmerman/mame
void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 offset, size_t length)
{
	UINT8 buffer[512];
	size_t this_length;

	memset(buffer, filler, MIN(length, sizeof(buffer)));

	while(length > 0)
	{
		this_length = MIN(length, sizeof(buffer));
		io_generic_write(generic, buffer, offset, this_length);
		offset += this_length;
		length -= this_length;
	}
}
コード例 #10
0
ファイル: rx50_dsk.cpp プロジェクト: MASHinfo/mame
bool rx50img_format::save(io_generic *io, floppy_image *image)
{
	int track_count, head_count, sector_count;
	get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);

	if(track_count != 80)
		track_count = 80;

	// Happens for a fully unformatted floppy
	if(!head_count)
		head_count = 1;

	if(sector_count == 9) // [VT180] 9 sector format : no save!
		return false;

	if(sector_count != 10) // either 8 or 10 sectors
		sector_count = 10; // [STANDARD]

	/*
	if(sector_count != 10) // either 8 or 10 sectors
	{
	  if(sector_count == 8)
	  {
	      track_count = 40;  // [DOS]
	  } else
	  {
	      sector_count = 10; // [STANDARD]
	  }
	}
*/
	uint8_t sectdata[11*512];
	int track_size = sector_count*512;

	for(int track=0; track < track_count; track++) {
		for(int head=0; head < head_count; head++) {
			get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
			io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
		}
	}
	return true;
}
コード例 #11
0
ファイル: coupedsk.cpp プロジェクト: MASHinfo/mame
bool mgt_format::save(io_generic *io, floppy_image *image)
{
	int track_count, head_count, sector_count;
	get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);

	if(sector_count > 10)
		sector_count = 10;
	else if(sector_count < 9)
		sector_count = 9;

	uint8_t sectdata[10*512];
	int track_size = sector_count*512;

	for(int head=0; head < 2; head++) {
		for(int track=0; track < 80; track++) {
			get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
			io_generic_write(io, sectdata, (head*80 + track)*track_size, track_size);
		}
	}

	return true;
}
コード例 #12
0
ファイル: upd765_dsk.c プロジェクト: Ilgrim/MAMEHub
bool upd765_format::save(io_generic *io, floppy_image *image)
{
	// Count the number of formats
	int formats_count;
	for(formats_count=0; formats[formats_count].form_factor; formats_count++);

	// Allocate the storage for the list of testable formats for a
	// given cell size
	int *candidates = global_alloc_array(int, formats_count);

	// Format we're finally choosing
	int chosen_candidate = -1;

	// Previously tested cell size
	int min_cell_size = 0;
	for(;;) {
		// Build the list of all formats for the immediatly superior cell size
		int cur_cell_size = 0;
		int candidates_count = 0;
		for(int i=0; i != formats_count; i++) {
			if(image->get_form_factor() == floppy_image::FF_UNKNOWN ||
				image->get_form_factor() == formats[i].form_factor) {
				if(formats[i].cell_size == cur_cell_size)
					candidates[candidates_count++] = i;
				else if((!cur_cell_size || formats[i].cell_size < cur_cell_size) &&
						formats[i].cell_size > min_cell_size) {
					candidates[0] = i;
					candidates_count = 1;
					cur_cell_size = formats[i].cell_size;
				}
			}
		}

		min_cell_size = cur_cell_size;

		// No candidates with a cell size bigger than the previously
		// tested one, we're done
		if(!candidates_count)
			break;

		// Filter with track 0 head 0
		check_compatibility(image, candidates, candidates_count);

		// Nobody matches, try with the next cell size
		if(!candidates_count)
			continue;

		// We have a match at that cell size, we just need to find the
		// best one given the geometry

		// If there's only one, we're done
		if(candidates_count == 1) {
			chosen_candidate = candidates[0];
			break;
		}

		// Otherwise, find the best
		int tracks, heads;
		image->get_actual_geometry(tracks, heads);
		chosen_candidate = candidates[0];
		for(int i=1; i != candidates_count; i++) {
			const format &cc = formats[chosen_candidate];
			const format &cn = formats[candidates[i]];

			// Handling enough sides is better than not
			if(cn.head_count >= heads && cc.head_count < heads)
				goto change;
			else if(cc.head_count >= heads && cn.head_count < heads)
				goto dont_change;

			// Since we're limited to two heads, at that point head
			// count is identical for both formats.

			// Handling enough tracks is better than not
			if(cn.track_count >= tracks && cc.track_count < tracks)
				goto change;
			else if(cn.track_count >= tracks && cc.track_count < tracks)
				goto dont_change;

			// Both are on the same side of the track count, so closest is best
			if(cc.track_count < tracks && cn.track_count > cc.track_count)
				goto change;
			if(cc.track_count >= tracks && cn.track_count < cc.track_count)
				goto change;
			goto dont_change;

		change:
			chosen_candidate = candidates[i];
		dont_change:
			;
		}
		// We have a winner, bail out
		break;
	}

	// No match, pick the first one and be done with it
	if(chosen_candidate == -1)
		chosen_candidate = 0;


	const format &f = formats[chosen_candidate];
	int track_size = compute_track_size(f);

	UINT8 sectdata[40*512];
	desc_s sectors[40];
	build_sector_description(f, sectdata, sectors);

	for(int track=0; track < f.track_count; track++)
		for(int head=0; head < f.head_count; head++) {
			extract_sectors(image, f, sectors, track, head);
			io_generic_write(io, sectdata, (track*f.head_count + head)*track_size, track_size);
		}

	return true;
}
コード例 #13
0
ファイル: flopimg.c プロジェクト: RobinDX/xmame
void floppy_image_write(floppy_image *floppy, const void *buffer, UINT64 offset, size_t length)
{
    io_generic_write(&floppy->io, buffer, offset, length);
}
コード例 #14
0
ファイル: wd177x_dsk.cpp プロジェクト: Robbbert/store1
bool wd177x_format::save(io_generic *io, floppy_image *image)
{
	// Count the number of formats
	int formats_count;
	for(formats_count=0; formats[formats_count].form_factor; formats_count++) {};

	// Allocate the storage for the list of testable formats for a
	// given cell size
	std::vector<int> candidates;

	// Format we're finally choosing
	int chosen_candidate = -1;

	// Previously tested cell size
	int min_cell_size = 0;
	for(;;) {
		// Build the list of all formats for the immediately superior cell size
		int cur_cell_size = 0;
		candidates.clear();
		for(int i=0; i != formats_count; i++) {
			if(image->get_form_factor() == floppy_image::FF_UNKNOWN ||
				image->get_form_factor() == formats[i].form_factor) {
				if(formats[i].cell_size == cur_cell_size)
					candidates.push_back(i);
				else if((!cur_cell_size || formats[i].cell_size < cur_cell_size) &&
						formats[i].cell_size > min_cell_size) {
					candidates.clear();
					candidates.push_back(i);
					cur_cell_size = formats[i].cell_size;
				}
			}
		}

		min_cell_size = cur_cell_size;

		// No candidates with a cell size bigger than the previously
		// tested one, we're done
		if(candidates.empty())
			break;

		// Filter with track 0 head 0
		check_compatibility(image, candidates);

		// Nobody matches, try with the next cell size
		if(candidates.empty())
			continue;

		// We have a match at that cell size, we just need to find the
		// best one given the geometry

		// If there's only one, we're done
		if(candidates.size() == 1) {
			chosen_candidate = candidates[0];
			break;
		}

		// Otherwise, find the best
		int tracks, heads;
		image->get_actual_geometry(tracks, heads);
		chosen_candidate = candidates[0];
		for(unsigned int i=1; i != candidates.size(); i++) {
			const format &cc = formats[chosen_candidate];
			const format &cn = formats[candidates[i]];

			// Handling enough sides is better than not
			if(cn.head_count >= heads && cc.head_count < heads)
				goto change;
			else if(cc.head_count >= heads && cn.head_count < heads)
				goto dont_change;

			// Handling enough tracks is better than not
			if(cn.track_count >= tracks && cc.track_count < tracks)
				goto change;
			else if(cc.track_count >= tracks && cn.track_count < tracks)
				goto dont_change;

			// Both are on the same side of the track count, so closest is best
			if(cc.track_count < tracks && cn.track_count > cc.track_count)
				goto change;
			if(cc.track_count >= tracks && cn.track_count < cc.track_count)
				goto change;

			// Lower number of heads is better
			if (cn.head_count < cc.head_count && cn.head_count <= heads)
				goto change;

			goto dont_change;

		change:
			chosen_candidate = candidates[i];
		dont_change:
			;
		}
		// We have a winner, bail out
		break;
	}

	// No match, pick the first one and be done with it
	if(chosen_candidate == -1)
		chosen_candidate = 0;


	const format &f = formats[chosen_candidate];
	int track_size = compute_track_size(f);

	uint8_t sectdata[40*512];
	desc_s sectors[40];

	for(int track=0; track < f.track_count; track++)
		for(int head=0; head < f.head_count; head++) {
			build_sector_description(f, sectdata, sectors, track, head);
			extract_sectors(image, f, sectors, track, head);
			io_generic_write(io, sectdata, get_image_offset(f, head, track), track_size);
		}

	return true;
}