示例#1
0
文件: wd177x_dsk.c 项目: dinkc64/mame
bool wd177x_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
	int type = find_size(io, form_factor);
	if(type == -1)
		return false;

	const format &f = formats[type];
	floppy_image_format_t::desc_e *desc;
	int current_size;
	int end_gap_index;

	switch (f.encoding)
	{
	case floppy_image::FM:
		desc = get_desc_fm(f, current_size, end_gap_index);
		break;
	case floppy_image::MFM:
	default:
		desc = get_desc_mfm(f, current_size, end_gap_index);
		break;
	}

	int total_size = 200000000/f.cell_size;
	int remaining_size = total_size - current_size;
	if(remaining_size < 0)
		throw emu_fatalerror("wd177x_format: Incorrect track layout, max_size=%d, current_size=%d", total_size, current_size);

	// Fixup the end gap
	desc[end_gap_index].p2 = remaining_size / 16;
	desc[end_gap_index + 1].p2 = remaining_size & 15;
	desc[end_gap_index + 1].p1 >>= 16-(remaining_size & 15);

	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++) {
			if (f.encoding == floppy_image::FM)
				desc[14].p1 = get_track_dam_fm(f, head, track);
			else
				desc[16].p1 = get_track_dam_mfm(f, head, track);

			io_generic_read(io, sectdata, get_image_offset(f, head, track), track_size);
			generate_track(desc, track, head, sectors, f.sector_count, total_size, image);
		}

	image->set_variant(f.variant);

	return true;
}
示例#2
0
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
	dynamic_array<int> candidates(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, get_image_offset(f, head, track), track_size);
		}

	return true;
}