Beispiel #1
0
void upd765_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head)
{
	UINT8 bitstream[500000/8];
	UINT8 sectdata[50000];
	desc_xs sectors[256];
	int track_size;

	// Extract the sectors
	generate_bitstream_from_track(track, head, f.cell_size, bitstream, track_size, image);

	switch (f.encoding)
	{
	case floppy_image::FM:
		extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata));
		break;
	case floppy_image::MFM:
		extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata));
		break;
	}

	for(int i=0; i<f.sector_count; i++) {
		desc_s &ds = sdesc[i];
		desc_xs &xs = sectors[ds.sector_id];
		if(!xs.data)
			memset((void *)ds.data, 0, ds.size);
		else if(xs.size < ds.size) {
			memcpy((void *)ds.data, xs.data, xs.size);
			memset((UINT8 *)ds.data + xs.size, 0, xs.size - ds.size);
		} else
			memcpy((void *)ds.data, xs.data, ds.size);
	}
}
Beispiel #2
0
int g64_format::generate_bitstream(int track, int head, int speed_zone, UINT8 *trackbuf, int &track_size, floppy_image *image)
{
	int cell_size = c1541_cell_size[speed_zone];

	generate_bitstream_from_track(track, head, cell_size, trackbuf, track_size, image);

	int actual_cell_size = 200000000L/track_size;

	// allow a tolerance of +- 10 us (3990..4010 -> 4000)
	return ((actual_cell_size >= cell_size-10) && (actual_cell_size <= cell_size+10)) ? speed_zone : -1;
}
Beispiel #3
0
void upd765_format::check_compatibility(floppy_image *image, int *candidates, int &candidates_count)
{
	UINT8 bitstream[500000/8];
	UINT8 sectdata[50000];
	desc_xs sectors[256];
	int track_size;

	// Extract the sectors
	generate_bitstream_from_track(0, 0, formats[candidates[0]].cell_size, bitstream, track_size, image);

	switch (formats[candidates[0]].encoding)
	{
	case floppy_image::FM:
		extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata));
		break;
	case floppy_image::MFM:
		extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata));
		break;
	}

	// Check compatibility with every candidate, copy in-place
	int *ok_cands = candidates;
	for(int i=0; i != candidates_count; i++) {
		const format &f = formats[candidates[i]];
		int ns = 0;
		for(int j=0; j<256; j++)
			if(sectors[j].data) {
				int sid;
				if(f.sector_base_id == -1) {
					for(sid=0; sid < f.sector_count; sid++)
						if(f.per_sector_id[sid] == j)
							break;
				} else
					sid = j - f.sector_base_id;
				if(sid < 0 || sid > f.sector_count)
					goto fail;
				if(f.sector_base_size) {
					if(sectors[j].size != f.sector_base_size)
						goto fail;
				} else {
					if(sectors[j].size != f.per_sector_size[sid])
						goto fail;
				}
				ns++;
			}
		if(ns == f.sector_count)
			*ok_cands++ = candidates[i];
	fail:
		;
	}
	candidates_count = ok_cands - candidates;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
bool ti99_floppy_format::save(io_generic *io, floppy_image *image)
{
	int act_track_size = 0;

	UINT8 bitstream[500000/8];
	UINT8 trackdata[9216];   // max size

	int cellsizes[] = { 2000, 4000, 1000, 2000 };

	// Do we use double-stepping?
	// If our image was loaded into a 80-track drive, we will always write 80 tracks.
	int maxtrack, maxheads;
	image->get_maximal_geometry(maxtrack, maxheads);

	if (maxtrack > 80) maxtrack = 80;
	else
	{
		if (maxtrack > 35 && maxtrack < 80) maxtrack = 40;
		else maxtrack = 35;
	}

	int attempt = 0;
	int sector[36];
	int maxsect = 18;
	bool write = true;

	// We expect a bitstream of length 50000 for FM and 100000 for MFM
	for(int head=0; head < 2; head++)
	{
		int track = 0;
		while (track < maxtrack)
		{
			int cell_size = cellsizes[attempt];
			int encoding = get_encoding(cell_size);
			int track_size = get_track_size(cell_size, 36); // max number of sectors

			// Retrieve the cells from the flux sequence
			generate_bitstream_from_track(track, head, cell_size, bitstream, act_track_size, image);

			// Maybe the track has become longer due to moving splices
			if (act_track_size > 200000000/cell_size) act_track_size = 200000000/cell_size;

			int marks = decode_bitstream(bitstream, trackdata, sector, act_track_size, encoding, (encoding==floppy_image::FM)? 0xff:0x4e, track_size);

			if (track==0)
			{
				if (head==0)
				{
					// Find the highest sector in the track
					// This is only needed for the SDF format
					int i=35;
					while (i>=0 && sector[i]==-1) i--;

					if (i>18) maxsect = 36;
					else
					{
						if (i>16) maxsect = 18;
						else
						{
							if (i>9) maxsect = 16;
							else maxsect = 9;
						}
					}
					if (TRACE) osd_printf_info("ti99_dsk: Sectors/track: %d\n", maxsect);

					// We try different cell sizes until we find a fitting size.
					// If this fails, we fall back to a size of 2000 ns
					// The criterion for a successful decoding is that we find at least
					// 6 ID or data address marks on the track. It is highly unlikely
					// to find so many marks with a wrong cell size.
					if (marks < 6 && attempt < 4)
					{
						if (TRACE) osd_printf_verbose("ti99_dsk: Decoding with cell size %d failed.\n", cell_size);
						attempt++;
						write = false;
					}
					else write = true;
				}
				else
				{
					if (marks < 6)
					{
						if (min_heads()==1)
						{
							if (TRACE) osd_printf_info("ti99_dsk: We don't have a second side and the format allows for single-sided recording.\n");
							return true;
						}
						else
						{
							osd_printf_warning("ti99_dsk: No second side, but this format requires two-sided recording. Saving empty tracks.\n");
						}
					}
				}
			}

			if (write)
			{
				if (TRACE)
				{
					if (head == 0 && track == 0)
					{
						if (marks >=6) { if (TRACE) osd_printf_info("ti99_dsk: Decoding with cell size %d successful.\n", cell_size); }
						else osd_printf_info("ti99_dsk: No address marks found on track 0. Assuming MFM format.\n");
					}
				}
				// Save to the file
				write_track(io, trackdata, sector, track, head, maxsect, maxtrack, track_size);
				track++;
			}
		}
	}

	return true;
}