Example #1
0
bool oric_dsk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
	UINT8 h[256];
	UINT8 t[6250+3];
	UINT32 stream[100000];

	t[6250] = t[6251] = t[6252] = 0;
	io_generic_read(io, h, 0, 256);

	int sides  = (h[11] << 24) | (h[10] << 16) | (h[ 9] << 8) | h[ 8];
	int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12];

	for(int side=0; side<sides; side++)
		for(int track=0; track<tracks; track++) {
			io_generic_read(io, t, 256+6400*(tracks*side + track), 6250);
			int pos = 0;
			int sector_size = 128;
			for(int i=0; i<6250; i++) {
				if(t[i] == 0xc2 && t[i+1] == 0xc2 && t[i+2] == 0xc2) {
					raw_w(stream, pos, 16, 0x5224);
					raw_w(stream, pos, 16, 0x5224);
					raw_w(stream, pos, 16, 0x5224);
					i += 2;
					continue;
				}
				if(t[i] == 0xa1 && t[i+1] == 0xa1 && t[i+2] == 0xa1) {
					raw_w(stream, pos, 16, 0x4489);
					raw_w(stream, pos, 16, 0x4489);
					raw_w(stream, pos, 16, 0x4489);
					int copy;
					if(t[i+3] == 0xfe) {
						copy = 7;
						sector_size = 128 << (t[i+7] & 3);
						logerror("%02x %x - %02x %02x %02x %02x\n",
									track, side, t[i+4], t[i+5], t[i+6], t[i+7]);
					} else if(t[i+3] == 0xfb)
						copy = sector_size+3;
					else
						copy = 0;
					for(int j=0; j<copy; j++)
						mfm_w(stream, pos, 8, t[i+3+j]);
					i += 2+copy;
					continue;
				}
				mfm_w(stream, pos, 8, t[i]);
			}
			generate_track_from_levels(track, side, stream, 100000, 0, image);
		}

	return true;
}
Example #2
0
bool dmk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
	const int header_size = 16;
	UINT8 header[header_size];

	io_generic_read(io, header, 0, header_size);

	const int tracks = header[1];
	const int track_size = ( header[3] << 8 ) | header[2];
	const int heads = (header[4] & 0x10) ? 1 : 2;
	const bool is_sd = (header[4] & 0x40) ? true : false;
	const int raw_track_size = 2 * 8 * ( track_size - 0x80 );

	if (is_sd)
	{
		if (heads == 2)
		{
			image->set_variant(floppy_image::DSSD);
		}
		else
		{
			image->set_variant(floppy_image::SSSD);
		}
	}
	else
	{
		if (heads == 2)
		{
			image->set_variant(floppy_image::DSDD);
		}
		else
		{
			image->set_variant(floppy_image::SSDD);
		}
	}

	for (int track = 0; track < tracks; track++)
	{
		for (int head = 0; head < heads; head++)
		{
			dynamic_array<UINT8> track_data(track_size);
			dynamic_array<UINT32> raw_track_data(raw_track_size);
			int iam_location = -1;
			int idam_location[64];
			int dam_location[64];
			int tpos = 0;

			// Read track
			io_generic_read(io, track_data, header_size + ( heads * track + head ) * track_size, track_size);

			for (int i = 0; i < 64; i++)
			{
				idam_location[i] = -1;
				dam_location[i] = -1;
			}

			// Find IDAM locations
			UINT16 track_header_offset = 0;
			UINT16 track_offset = ( ( track_data[track_header_offset + 1] << 8 ) | track_data[track_header_offset] ) & 0x3fff;
			track_header_offset += 2;

			while ( track_offset != 0 && track_offset >= 0x83 && track_offset < track_size && track_header_offset < 0x80 )
			{
				// Assume 3 bytes before IDAM pointers are the start of IDAM indicators
				idam_location[(track_header_offset/2) - 1] = track_offset - 3;

				// Scan for DAM location
				for (int i = track_offset + 53; i > track_offset + 10; i--)
				{
					if ((track_data[i] == 0xfb || track_data[i] == 0xf8) && track_data[i-1] == 0xa1 && track_data[i-2] == 0xa1)
					{
						dam_location[(track_header_offset/2) - 1] = i - 3;
						break;
					}
				}

				track_offset = ( ( track_data[track_header_offset + 1] << 8 ) | track_data[track_header_offset] ) & 0x3fff;
				track_header_offset += 2;
			};

			// Find IAM location
			for(int i = idam_location[0] - 1; i >= 3; i--)
			{
				// It's usually 3 bytes but several dumped tracks seem to contain only 2 bytes
				if (track_data[i] == 0xfc && track_data[i-1] == 0xc2 && track_data[i-2] == 0xc2)
				{
					iam_location = i - 3;
					break;
				}
			}

			int idam_index = 0;
			int dam_index = 0;
			for (int offset = 0x80; offset < track_size; offset++)
			{
				if (offset == iam_location)
				{
					// Write IAM
					raw_w(raw_track_data, tpos, 16, 0x5224);
					raw_w(raw_track_data, tpos, 16, 0x5224);
					raw_w(raw_track_data, tpos, 16, 0x5224);
					offset += 3;
				}

				if (offset == idam_location[idam_index])
				{
					raw_w(raw_track_data, tpos, 16, 0x4489);
					raw_w(raw_track_data, tpos, 16, 0x4489);
					raw_w(raw_track_data, tpos, 16, 0x4489);
					idam_index += 1;
					offset += 3;
				}

				if (offset == dam_location[dam_index])
				{
					raw_w(raw_track_data, tpos, 16, 0x4489);
					raw_w(raw_track_data, tpos, 16, 0x4489);
					raw_w(raw_track_data, tpos, 16, 0x4489);
					dam_index += 1;
					offset += 3;
				}

				mfm_w(raw_track_data, tpos, 8, track_data[offset]);
			}

			generate_track_from_levels(track, head, raw_track_data, raw_track_size, 0, image);
		}
	}

	return true;
}
Example #3
0
bool d88_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
{
	UINT8 h[32];

	io_generic_read(io, h, 0, 32);

	int cell_count = 0;
	int track_count = 0;
	int head_count = 0;
	switch(h[0x1b]) {
	case 0x00:
		cell_count = 100000;
		track_count = 42;
		head_count = 2;
		image->set_variant(floppy_image::DSDD);
		break;

	case 0x10:
		cell_count = 100000;
		track_count = 82;
		head_count = 2;
		image->set_variant(floppy_image::DSQD);
		break;

	case 0x20:
		cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666;
		track_count = 82;
		head_count = 2;
		image->set_variant(floppy_image::DSHD);
		break;

	case 0x30:
		cell_count = 100000;
		track_count = 42;
		head_count = 1;
		image->set_variant(floppy_image::SSDD);
		break;

	case 0x40:
		cell_count = 100000;
		track_count = 82;
		head_count = 1;
		image->set_variant(floppy_image::SSQD);
		break;
	}

	if(!head_count)
		return false;

	UINT32 track_pos[164];
	io_generic_read(io, track_pos, 32, 164*4);

	for(int track=0; track < track_count; track++)
		for(int head=0; head < head_count; head++) {
			int pos = LITTLE_ENDIANIZE_INT32(track_pos[track * head_count + head]);
			if(!pos)
				continue;

			UINT32 track_data[210000];
			UINT8 sect_data[65536];
			int tpos = 0;

			// gap 4a , IAM and gap 1
			for(int i=0; i<80; i++) mfm_w(track_data, tpos, 8, 0x4e);
			for(int i=0; i<12; i++) mfm_w(track_data, tpos, 8, 0x00);
			for(int i=0; i< 3; i++) raw_w(track_data, tpos, 16, 0x5224);
			mfm_w(track_data, tpos, 8, 0xfc);
			for(int i=0; i<50; i++) mfm_w(track_data, tpos, 8, 0x4e);

			// Updated after reading the first header
			int sector_count = 1;
			int gap3 = 84;
			for(int i=0; i<sector_count; i++) {
				UINT8 hs[16];
				io_generic_read(io, hs, pos, 16);
				UINT16 size = LITTLE_ENDIANIZE_INT16(*(UINT16 *)(hs+14));
				io_generic_read(io, sect_data, pos+16, size);
				pos += 16+size;

				if(i == 0) {
					sector_count = LITTLE_ENDIANIZE_INT16(*(UINT16 *)(hs+4));
					if(size < 512)
						gap3 = form_factor == floppy_image::FF_35 ? 54 : 50;
					else
						gap3 = form_factor == floppy_image::FF_35 ? 84 : 80;
				}

				int cpos;
				UINT16 crc;
				// sync and IDAM and gap 2
				for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00);
				cpos = tpos;
				for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489);
				mfm_w(track_data, tpos, 8, 0xfe);
				mfm_w(track_data, tpos, 8, hs[0]);
				mfm_w(track_data, tpos, 8, hs[1]);
				mfm_w(track_data, tpos, 8, hs[2]);
				mfm_w(track_data, tpos, 8, hs[3]);
				crc = calc_crc_ccitt(track_data, cpos, tpos);
				mfm_w(track_data, tpos, 16, crc);
				for(int j=0; j<22; j++) mfm_w(track_data, tpos, 8, 0x4e);

				// sync, DAM, data and gap 3
				for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00);
				cpos = tpos;
				for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489);
				mfm_w(track_data, tpos, 8, 0xfb);
				for(int j=0; j<size; j++) mfm_w(track_data, tpos, 8, sect_data[j]);
				crc = calc_crc_ccitt(track_data, cpos, tpos);
				mfm_w(track_data, tpos, 16, crc);
				for(int j=0; j<gap3; j++) mfm_w(track_data, tpos, 8, 0x4e);
			}

			// Gap 4b

			if(tpos > cell_count)
				throw emu_fatalerror("d88_format: Incorrect layout on track %d head %d, expected_size=%d, current_size=%d", track, head, cell_count, tpos);
			while(tpos < cell_count-15) mfm_w(track_data, tpos, 8, 0x4e);
			raw_w(track_data, tpos, cell_count-tpos, 0x9254 >> (16+tpos-cell_count));

			generate_track_from_levels(track, head, track_data, cell_count, 0, image);
		}

	return true;
}