예제 #1
0
파일: d81.cpp 프로젝트: d235j/samdisk
bool ReadD81 (MemFile &file, std::shared_ptr<Disk> &disk)
{
	// D81 is a fixed-size image
	uint8_t ab[256];
	if (file.size() != D81_DISK_SIZE || !file.seek(D81_HEADER_OFFSET) || !file.read(&ab, sizeof(ab)))
		return false;

	// Check for 1581 signature and various check bytes
	if (ab[2] != 'D' || ab[3] || ab[0x14] != 0xa0 || ab[0x15] != 0xa0 || ab[0x1b] != 0xa0 || ab[0x1c] != 0xa0)
		return false;

	Format fmt { RegularFormat::D81 };

	// D2M stores the sides in the reverse order, so fiddle things to read it easily
	file.rewind();
	std::swap(fmt.head0, fmt.head1);
	disk->format(fmt, file.data());
	std::swap(disk->fmt.head0, disk->fmt.head1);
	disk->flip_sides();
	disk->strType = "D81";

	return true;
}
예제 #2
0
파일: scp.cpp 프로젝트: d235j/samdisk
bool ReadSCP (MemFile &file, std::shared_ptr<Disk> &disk)
{
	SCP_FILE_HEADER fh {};

	if (!file.rewind() || !file.read(&fh, sizeof(fh)) || std::string(fh.signature, 3) != "SCP")
		return false;

	/*if (!(fh.flags & FLAG_INDEX))
		throw util::exception("not an index-synchronised image");
	else*/ if (fh.revolutions == 0 || fh.revolutions > 10)
		throw util::exception("invalid revolution count (", fh.revolutions, ")");
	else if (fh.bitcell_width != 0 && fh.bitcell_width != 16)
		throw util::exception("unsupported bit cell width (", fh.bitcell_width, ")");
	else if (fh.start_track > fh.end_track)
		throw util::exception("start track (", fh.start_track, ") > end track (", fh.end_track, ")");

	std::vector<uint32_t> tdh_offsets(fh.end_track + 1);
	if (!file.read(tdh_offsets))
		throw util::exception("short file reading track offset index");

	auto scp_disk = std::make_shared<SCPDisk>();

	for (auto tracknr = fh.start_track; tracknr <= fh.end_track; ++tracknr)
	{
		TRACK_DATA_HEADER tdh;
		auto cyl = tracknr >> 1;
		auto head = tracknr & 1;
		CylHead cylhead(cyl, head);

		if (!tdh_offsets[tracknr])
			continue;

		if (!file.seek(tdh_offsets[tracknr]) || !file.read(&tdh, sizeof(tdh)))
			throw util::exception("short file reading ", cylhead, " track header");
		else if (std::string(tdh.signature, 3) != "TRK")
			throw util::exception("invalid track signature on ", cylhead);
		else if (tdh.tracknr != tracknr)
			throw util::exception("track number mismatch (", tdh.tracknr, " != ", tracknr, ") in ", cylhead, " header");

		std::vector<uint32_t> rev_index(fh.revolutions * 3);
		if (!file.read(rev_index))
			throw util::exception("short file reading ", cylhead, " track index");

		std::vector<std::vector<uint16_t>> revs_data;
		revs_data.reserve(fh.revolutions);

		for (uint8_t rev = 0; rev < fh.revolutions; ++rev)
		{
//			auto index_time  = util::letoh<uint32_t>(rev_index[rev * 3 + 0]);
			auto flux_count = util::letoh<uint32_t>(rev_index[rev * 3 + 1]);
			auto data_offset = util::letoh<uint32_t>(rev_index[rev * 3 + 2]);

			std::vector<uint16_t> flux_data(flux_count);
			if (!file.seek(tdh_offsets[tracknr] + data_offset) || !file.read(flux_data))
				throw util::exception("short error reading ", cylhead, " data");

			revs_data.push_back(std::move(flux_data));
		}

		scp_disk->add_track_data(cylhead, std::move(revs_data));
	}

	scp_disk->strType = "SCP";
	disk = scp_disk;

	return true;
}