Exemple #1
0
static floperr_t put_bml3_dirent(imgtool_image *f, int index_loc, const struct bml3_dirent *ent)
{
	floperr_t err;
	UINT8 head, track, sector, offset;
	UINT8 buf[32];
	bml3_diskinfo *info = bml3_get_diskinfo(f);
	if (index_loc >= max_dirents(f))
		return (floperr_t)IMGTOOLERR_FILENOTFOUND;
	dirent_location(f, index_loc, &head, &track, &sector, &offset);
	memset(buf, 0, sizeof(buf));
	switch (info->variant) {
	case 0:
		memcpy(&buf[0], &ent->fname, 8);
		buf[11] = ent->ftype;
		buf[12] = ent->asciiflag;
		buf[14] = ent->first_granule;
		break;
	case 1:
		memcpy(&buf[0], &ent->fname, 8);
		memcpy(&buf[8], &ent->fext, 3);
		buf[11] = ent->ftype;
		buf[12] = ent->asciiflag;
		buf[13] = ent->first_granule;
		buf[14] = ent->lastsectorbytes >> 8;
		buf[15] = ent->lastsectorbytes & 0xff;
		break;
	default:
		return FLOPPY_ERROR_INVALIDIMAGE;
	}
	err = floppy_write_sector(imgtool_floppy(f), head, track, sector, offset, (void *) buf, sizeof(buf), 0); /* TODO: pass ddam argument from imgtool */
	return err;
}
Exemple #2
0
static floperr_t get_bml3_dirent(imgtool_image *f, int index_loc, struct bml3_dirent *ent)
{
	floperr_t err;
	UINT8 head, track, sector, offset;
	UINT8 buf[32];
	bml3_diskinfo *info = bml3_get_diskinfo(f);
	dirent_location(f, index_loc, &head, &track, &sector, &offset);
	err = floppy_read_sector(imgtool_floppy(f), head, track, sector, offset, (void *) buf, sizeof(buf));
	memset(ent, 0, sizeof(*ent));
	switch (info->variant) {
	case 0:
		memcpy(&ent->fname, &buf[0], 8);
		ent->ftype = buf[11];
		ent->asciiflag = buf[12];
		ent->first_granule = buf[14];
		break;
	case 1:
		memcpy(&ent->fname, &buf[0], 8);
		memcpy(&ent->fext, &buf[8], 3);
		ent->ftype = buf[11];
		ent->asciiflag = buf[12];
		ent->first_granule = buf[13];
		ent->lastsectorbytes = (buf[14] << 8) | buf[15];
		break;
	default:
		return FLOPPY_ERROR_INVALIDIMAGE;
	}
	return err;
}
Exemple #3
0
static imgtoolerr_t imgtool_floppy_transfer_sector_tofrom_stream(imgtool_image *img, int head, int track, int sector, int offset, size_t length, imgtool_stream *f, int direction)
{
	floperr_t err;
	floppy_image_legacy *floppy;
	dynamic_buffer buffer;

	floppy = imgtool_floppy(img);

	buffer.resize(length);

	if (direction)
	{
		err = floppy_read_sector(floppy, head, track, sector, offset, buffer, length);
		if (err)
			goto done;
		stream_write(f, buffer, length);
	}
	else
	{
		stream_read(f, buffer, length);
		err = floppy_write_sector(floppy, head, track, sector, offset, buffer, length, 0);  /* TODO: pass ddam argument from imgtool */
		if (err)
			goto done;
	}

	err = FLOPPY_ERROR_SUCCESS;

done:
	return imgtool_floppy_error(err);
}
Exemple #4
0
static UINT8 get_granule_count(imgtool_image *img)
{
    UINT16 tracks;
    UINT16 granules;

    tracks = floppy_get_tracks_per_disk(imgtool_floppy(img));
    granules = (tracks - 1) * 2;
    return (granules > 255) ? 255 : (UINT8) granules;
}
Exemple #5
0
static uint8_t get_granule_count(imgtool::image &img)
{
	uint16_t tracks;
	uint16_t granules;

	tracks = floppy_get_tracks_per_disk(imgtool_floppy(img));
	granules = (tracks - 1) * 2;
	return (granules > 255) ? 255 : (uint8_t) granules;
}
Exemple #6
0
static imgtoolerr_t imgtool_floppy_write_sector(imgtool_image *image, UINT32 track, UINT32 head, UINT32 sector, const void *buffer, size_t len, int ddam)
{
	floperr_t ferr;

	ferr = floppy_write_sector(imgtool_floppy(image), head, track, sector, 0, buffer, len, ddam);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Exemple #7
0
/* granule_map must be an array of MAX_GRANULEMAP_SIZE bytes */
static floperr_t get_granule_map(imgtool_image *img, UINT8 *granule_map, UINT8 *granule_count)
{
    UINT8 count;

    count = get_granule_count(img);
    if (granule_count)
        *granule_count = count;

    return floppy_read_sector(imgtool_floppy(img), 0, 17, 2, 0, granule_map, count);
}
Exemple #8
0
static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint8_t granule_count[MAX_GRANULEMAP_SIZE])
{
	uint8_t count;

	count = get_granule_count(img);
	if (granule_count)
		*granule_count = count;

	return floppy_read_sector(imgtool_floppy(img), 0, 17, 2, 0, granule_map, count);
}
Exemple #9
0
static imgtoolerr_t imgtool_floppy_get_sector_size(imgtool_image *image, UINT32 track, UINT32 head, UINT32 sector, UINT32 *sector_size)
{
	floperr_t ferr;

	ferr = floppy_get_sector_length(imgtool_floppy(image), head, track, sector, sector_size);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Exemple #10
0
/* granule_map must be an array of MAX_GRANULEMAP_SIZE bytes */
static floperr_t get_granule_map(imgtool_image *img, UINT8 *granule_map, UINT8 *granule_count)
{
	bml3_diskinfo *info = bml3_get_diskinfo(img);
	UINT8 count;

	count = get_granule_count(img);
	if (granule_count)
		*granule_count = count;

	// The first byte of the granule map sector is ignored (and expected to be 0)
	return floppy_read_sector(imgtool_floppy(img), 0, 20, info->fat_start_sector, info->fat_start_offset, granule_map, count);
}
Exemple #11
0
static imgtoolerr_t os9_read_lsn(imgtool_image *img, UINT32 lsn, int offset, void *buffer, size_t buffer_len)
{
	imgtoolerr_t err;
	floperr_t ferr;
	UINT32 head, track, sector;

	err = os9_locate_lsn(img, lsn, &head, &track, &sector);
	if (err)
		return err;

	ferr = floppy_read_sector(imgtool_floppy(img), head, track, sector, offset, buffer, buffer_len);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Exemple #12
0
/* write data to sector */
static imgtoolerr_t vzdos_write_sector_data(imgtool_image *img, int track, int sector, UINT8 *data)
{
	int ret, data_start;
	UINT8 buffer[DATA_SIZE + 4]; /* data + checksum */

	ret = vzdos_get_data_start(img, track, sector, &data_start);
	if (ret) return (imgtoolerr_t)ret;

	memcpy(buffer, data, DATA_SIZE + 2);
	place_integer_le(buffer, DATA_SIZE + 2, 2, chksum16(data, DATA_SIZE + 2));

	ret = floppy_write_sector(imgtool_floppy(img), 0, track, sector_order[sector], data_start, buffer, sizeof(buffer), 0);	/* TODO: pass ddam argument from imgtool */
	if (ret) return (imgtoolerr_t)ret;

	return IMGTOOLERR_SUCCESS;
}
Exemple #13
0
static imgtoolerr_t os9_write_lsn(imgtool_image *img, UINT32 lsn, int offset, const void *buffer, size_t buffer_len)
{
	imgtoolerr_t err;
	floperr_t ferr;
	UINT32 head, track, sector;

	err = os9_locate_lsn(img, lsn, &head, &track, &sector);
	if (err)
		return err;

	ferr = floppy_write_sector(imgtool_floppy(img), head, track, sector, offset, buffer, buffer_len, 0);    /* TODO: pass ddam argument from imgtool */
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Exemple #14
0
static imgtoolerr_t bml3_diskimage_open(imgtool_image *image, imgtool_stream *stream)
{
	// imgtoolerr_t err;
	floperr_t ferr;
	bml3_diskinfo *info = bml3_get_diskinfo(image);
	floppy_image_legacy *floppy = imgtool_floppy(image);
	const struct FloppyCallbacks *callbacks = floppy_callbacks(floppy);

	// probe disk geometry to guess format
	int heads_per_disk = callbacks->get_heads_per_disk(floppy);
	UINT32 sector_length;
	ferr = callbacks->get_sector_length(floppy, 0, 20, 1, &sector_length);
	if (ferr)
		return imgtool_floppy_error(ferr);
	int sectors_per_track = callbacks->get_sectors_per_track(floppy, 0, 20);

	if (heads_per_disk == 2 && sector_length == 128 && sectors_per_track == 16) {
		// single-sided, single-density
		info->sector_size = 128;
		info->heads = 1;
		info->fat_start_sector = 1;
		info->fat_start_offset = 5;
		info->fat_sectors = 2;
		info->dirent_start_sector = 7;
		info->granule_sectors = 4;
		info->first_granule_cylinder = 0;
		info->variant = 0;
	}
	else if (heads_per_disk == 2 && sector_length == 256 && sectors_per_track == 16) {
		// double-sided, double-density
		info->sector_size = 256;
		info->heads = 2;
		info->fat_start_sector = 2;
		info->fat_start_offset = 1;
		info->fat_sectors = 1;
		info->dirent_start_sector = 5;
		info->granule_sectors = 8;
		info->first_granule_cylinder = 1;
		info->variant = 1;
	}
	else {
		// invalid or unsupported format
		return IMGTOOLERR_CORRUPTIMAGE;
	}

	return IMGTOOLERR_SUCCESS;
}
Exemple #15
0
/* return the actual data of a sector */
static imgtoolerr_t vzdos_read_sector_data(imgtool_image *img, int track, int sector, UINT8 *data)
{
	int ret, data_start;
	UINT8 buffer[DATA_SIZE + 4]; /* data + checksum */

	ret = vzdos_get_data_start(img, track, sector, &data_start);
	if (ret) return (imgtoolerr_t)ret;

	ret = floppy_read_sector(imgtool_floppy(img), 0, track, sector_order[sector], data_start, &buffer, sizeof(buffer));
	if (ret) return (imgtoolerr_t)ret;

	/* verify sector checksums */
	if (pick_integer_le(buffer, DATA_SIZE + 2, 2) != chksum16(buffer, DATA_SIZE + 2))
		return IMGTOOLERR_CORRUPTFILE;

	memcpy(data, &buffer, DATA_SIZE + 2);

	return IMGTOOLERR_SUCCESS;
}
Exemple #16
0
/* returns the offset where the actual sector data starts */
static imgtoolerr_t vzdos_get_data_start(imgtool_image *img, int track, int sector, int *start)
{
	imgtoolerr_t ret;
	UINT8 buffer[25]; /* enough to read the sector header */

	ret = (imgtoolerr_t)floppy_read_sector(imgtool_floppy(img), 0, track, sector_order[sector], 0, &buffer, sizeof(buffer));
	if (ret) return ret;

	/* search for start of data */
	if (memcmp(buffer + 19, "\xC3\x18\xE7\xFE", 4) == 0)
		*start = 23;
	else if (memcmp(buffer + 20, "\xC3\x18\xE7\xFE", 4) == 0)
		*start = 24;
	else if (memcmp(buffer + 21, "\xC3\x18\xE7\xFE", 4) == 0)
		*start = 25;
	else
		return IMGTOOLERR_CORRUPTIMAGE;

	return IMGTOOLERR_SUCCESS;
}
Exemple #17
0
static imgtoolerr_t vzdos_write_formatted_sector(imgtool_image *img, int track, int sector)
{
	int ret;
	UINT8 sector_data[DATA_SIZE + 4 + 24];

	static const UINT8 sector_header[24] = {
		0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFE, 0xE7,
		0x18, 0xC3, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
		0x80, 0x80, 0x80, 0x00, 0xC3, 0x18, 0xE7, 0xFE
	};

	memset(sector_data, 0x00, sizeof(sector_data));
	memcpy(sector_data, sector_header, sizeof(sector_header));

	sector_data[10] = (UINT8) track;			/* current track */
	sector_data[11] = (UINT8) sector;			/* current sector */
	sector_data[12] = (UINT8) track + sector;	/* checksum-8 */

	ret = floppy_write_sector(imgtool_floppy(img), 0, track, sector_order[sector], 0, sector_data, sizeof(sector_data), 0);	/* TODO: pass ddam argument from imgtool */
	if (ret) return (imgtoolerr_t)ret;

	return IMGTOOLERR_SUCCESS;
}
Exemple #18
0
static imgtoolerr_t imgtool_floppy_transfer_sector_tofrom_stream(imgtool_image *img, int head, int track, int sector, int offset, size_t length, imgtool_stream *f, int direction)
{
	floperr_t err;
	floppy_image_legacy *floppy;
	void *buffer = NULL;

	floppy = imgtool_floppy(img);

	buffer = malloc(length);
	if (!buffer)
	{
		err = FLOPPY_ERROR_OUTOFMEMORY;
		goto done;
	}

	if (direction)
	{
		err = floppy_read_sector(floppy, head, track, sector, offset, buffer, length);
		if (err)
			goto done;
		stream_write(f, buffer, length);
	}
	else
	{
		stream_read(f, buffer, length);
		err = floppy_write_sector(floppy, head, track, sector, offset, buffer, length, 0);	/* TODO: pass ddam argument from imgtool */
		if (err)
			goto done;
	}

	err = FLOPPY_ERROR_SUCCESS;

done:
	if (buffer)
		free(buffer);
	return imgtool_floppy_error(err);
}
Exemple #19
0
static floperr_t get_rsdos_dirent(imgtool_image *f, int index_loc, struct rsdos_dirent *ent)
{
    return floppy_read_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) ent, sizeof(*ent));
}
Exemple #20
0
static floperr_t write_granule(imgtool_image *img, UINT8 granule, int offset, int length, const UINT8 *buf)
{
	UINT8 head, track, sector;
	granule_location(img, granule, &head, &track, &sector);
	return floppy_write_sector(imgtool_floppy(img), head, track, sector, offset, buf, length, 0); /* TODO: pass ddam argument from imgtool */
}
Exemple #21
0
static floperr_t read_granule(imgtool_image *img, UINT8 granule, int offset, int length, UINT8 *buf)
{
	UINT8 head, track, sector;
	granule_location(img, granule, &head, &track, &sector);
	return floppy_read_sector(imgtool_floppy(img), head, track, sector, offset, buf, length);
}
Exemple #22
0
static floperr_t put_rsdos_dirent(imgtool::image &f, int index_loc, const rsdos_dirent &ent)
{
	if (index_loc >= MAX_DIRENTS)
		return (floperr_t)IMGTOOLERR_FILENOTFOUND;
	return floppy_write_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) &ent, sizeof(ent), 0); /* TODO: pass ddam argument from imgtool */
}
Exemple #23
0
static void imgtool_floppy_close(imgtool_image *img)
{
	floppy_close(imgtool_floppy(img));
}
Exemple #24
0
static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, const char *fname, const char *fork, imgtool::stream &sourcef, util::option_resolution *writeoptions)
{
	floperr_t ferr;
	imgtoolerr_t err;
	imgtool::image &img(partition.image());
	struct rsdos_dirent ent, ent2;
	size_t i;
	uint64_t sz;
	uint64_t freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	uint8_t granule_count;
	uint8_t granule_map[MAX_GRANULEMAP_SIZE];

	// can we write to this image?
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	err = rsdos_diskimage_freespace(partition, &freespace);
	if (err)
		return err;

	// is there enough space?
	sz = sourcef.size();
	if (sz > freespace)
		return IMGTOOLERR_NOSPACE;

	// setup our directory entry
	err = prepare_dirent(ent, fname);
	if (err)
		return err;

	ent.ftype = writeoptions->lookup_int(RSDOS_OPTIONS_FTYPE);
	ent.asciiflag = uint8_t(writeoptions->lookup_int(RSDOS_OPTIONS_ASCII)) - 1;
	ent.lastsectorbytes_lsb = sz % 256;
	ent.lastsectorbytes_msb = (((sz % 256) == 0) && (sz > 0)) ? 1 : 0;
	gptr = &ent.first_granule;

	ferr = get_granule_map(img, granule_map, &granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	g = 0x00;

	do
	{
		while (granule_map[g] != 0xff)
		{
			g++;
			if ((g >= granule_count) || (g == 0))
				return IMGTOOLERR_UNEXPECTED;   // we should have already verified that there is enough space
		}
		*gptr = g;
		gptr = &granule_map[g];


		i = std::min(sz, uint64_t(9*256));
		err = transfer_to_granule(img, g, i, sourcef);
		if (err)
			return err;

		sz -= i;

		// go to next granule
		g++;
	}
	while(sz > 0);

	// now that we are done with the file, we need to specify the final entry
	// in the file allocation table
	*gptr = 0xc0 + ((i + 255) / 256);

	// now we need to find an empty directory entry
	i = -1;
	do
	{
		ferr = get_rsdos_dirent(img, ++i, ent2);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while((ent2.filename[0] != '\0') && strcmp(ent.filename, ent2.filename) && (ent2.filename[0] != -1));

	// delete file if it already exists
	if (ent2.filename[0] && (ent2.filename[0] != -1))
	{
		err = delete_entry(img, ent2, i);
		if (err)
			return err;
	}

	ferr = put_rsdos_dirent(img, i, ent);
	if (ferr)
		return imgtool_floppy_error(ferr);

	// write the granule map back out
	ferr = put_granule_map(img, granule_map, granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Exemple #25
0
static floperr_t get_rsdos_dirent(imgtool::image &f, int index_loc, rsdos_dirent &ent)
{
	return floppy_read_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) &ent, sizeof(ent));
}
Exemple #26
0
static floperr_t put_granule_map(imgtool::image &img, const uint8_t *granule_map, uint8_t granule_count)
{
	return floppy_write_sector(imgtool_floppy(img), 0, 17, 2, 0, granule_map, granule_count, 0);    /* TODO: pass ddam argument from imgtool */
}
Exemple #27
0
static imgtoolerr_t bml3_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions)
{
	floperr_t ferr;
	imgtoolerr_t err;
	imgtool_image *img = imgtool_partition_image(partition);
	bml3_diskinfo *info = bml3_get_diskinfo(img);
	struct bml3_dirent ent, ent2;
	size_t i;
	UINT64 sz, read_sz;
	UINT64 freespace = 0;
	unsigned char g;
	unsigned char *gptr;
	UINT8 granule_count;
	UINT8 granule_map[MAX_GRANULEMAP_SIZE];
	UINT8 eof_buf[MAX_SECTOR_SIZE];

	// one-time setup of eof_buf
	memset(eof_buf, 0, sizeof(eof_buf));
	eof_buf[0] = 0x1A;

	/* can we write to this image? */
	if (floppy_is_read_only(imgtool_floppy(img)))
		return IMGTOOLERR_READONLY;

	err = bml3_diskimage_freespace(partition, &freespace);
	if (err)
		return err;

	/* is there enough space? */
	sz = read_sz = stream_size(sourcef);
	if (info->variant == 0) {
		// also need to write EOF
		sz++;
	}
	if (sz > freespace)
		return IMGTOOLERR_NOSPACE;

	/* setup our directory entry */
	err = prepare_dirent(info->variant, &ent, fname);
	if (err)
		return err;

	ent.ftype = option_resolution_lookup_int(writeoptions, BML3_OPTIONS_FTYPE);
	ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, BML3_OPTIONS_ASCII)) - 1;
	gptr = &ent.first_granule;

	ferr = get_granule_map(img, granule_map, &granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	g = 0x00;

	do
	{
		while (granule_map[g] != 0xff)
		{
			g++;
			if ((g >= granule_count) || (g == 0))
				return IMGTOOLERR_UNEXPECTED;   /* We should have already verified that there is enough space */
		}
		*gptr = g;
		gptr = &granule_map[g];


		i = MIN(read_sz, info->granule_sectors * info->sector_size);
		if (i > 0) {
			err = transfer_to_granule(img, g, i, sourcef);
			if (err)
				return err;
			read_sz -= i;
			sz -= i;
		}
		if (i < info->granule_sectors * info->sector_size && sz > 0) {
			// write EOF and trailing NULs in the final sector
			ferr = write_granule(img, g, i, (info->granule_sectors * info->sector_size - i - 1) % info->sector_size + 1, eof_buf);
			if (ferr)
				return imgtool_floppy_error(ferr);
			sz--;
			i++;
		}

		/* Go to next granule */
		g++;
	}
	while(sz > 0);

	/* Now that we are done with the file, we need to specify the final entry
	 * in the file allocation table
	 */
	*gptr = 0xc0 + ((i + info->sector_size-1) / info->sector_size) - (info->variant == 0 ? 1 : 0);
	ent.lastsectorbytes = (i - 1) % info->sector_size + 1;

	/* delete file if it already exists */
	err = bml3_diskimage_deletefile(partition, fname);
	if (err && err != IMGTOOLERR_FILENOTFOUND)
		return err;

	/* Now we need to find an empty directory entry */
	i = -1;
	do
	{
		ferr = get_bml3_dirent(img, ++i, &ent2);
		if (ferr)
			return imgtool_floppy_error(ferr);
	}
	while(ent2.fname[0] != '\0' && ent2.fname[0] != -1);

	ferr = put_bml3_dirent(img, i, &ent);
	if (ferr)
		return imgtool_floppy_error(ferr);

	/* write the granule map back out */
	ferr = put_granule_map(img, granule_map, granule_count);
	if (ferr)
		return imgtool_floppy_error(ferr);

	return IMGTOOLERR_SUCCESS;
}
Exemple #28
0
static floperr_t put_granule_map(imgtool_image *img, const UINT8 *granule_map, UINT8 granule_count)
{
    return floppy_write_sector(imgtool_floppy(img), 0, 17, 2, 0, granule_map, granule_count, 0);    /* TODO: pass ddam argument from imgtool */
}
Exemple #29
0
static imgtoolerr_t os9_diskimage_create(imgtool_image *img, imgtool_stream *stream, option_resolution *opts)
{
	imgtoolerr_t err;
	dynamic_buffer header;
	UINT32 heads, tracks, sectors, sector_bytes, first_sector_id;
	UINT32 cluster_size, owner_id;
	UINT32 allocation_bitmap_bits, allocation_bitmap_lsns;
	UINT32 attributes, format_flags, disk_id;
	UINT32 i;
	INT32 total_allocated_sectors;
	const char *title;
	time_t t;
	struct tm *ltime;

	time(&t);
	ltime = localtime(&t);

	heads = option_resolution_lookup_int(opts, 'H');
	tracks = option_resolution_lookup_int(opts, 'T');
	sectors = option_resolution_lookup_int(opts, 'S');
	sector_bytes = option_resolution_lookup_int(opts, 'L');
	first_sector_id = option_resolution_lookup_int(opts, 'F');
	title = "";

	header.resize(sector_bytes);

	if (sector_bytes > 256)
		sector_bytes = 256;
	cluster_size = 1;
	owner_id = 1;
	disk_id = 1;
	attributes = 0;
	allocation_bitmap_bits = heads * tracks * sectors / cluster_size;
	allocation_bitmap_lsns = (allocation_bitmap_bits / 8 + sector_bytes - 1) / sector_bytes;
	format_flags = ((heads > 1) ? 0x01 : 0x00) | ((tracks > 40) ? 0x02 : 0x00);

	memset(&header[0], 0, sector_bytes);
	place_integer_be(&header[0],   0,  3, heads * tracks * sectors);
	place_integer_be(&header[0],   3,  1, sectors);
	place_integer_be(&header[0],   4,  2, (allocation_bitmap_bits + 7) / 8);
	place_integer_be(&header[0],   6,  2, cluster_size);
	place_integer_be(&header[0],   8,  3, 1 + allocation_bitmap_lsns);
	place_integer_be(&header[0],  11,  2, owner_id);
	place_integer_be(&header[0],  13,  1, attributes);
	place_integer_be(&header[0],  14,  2, disk_id);
	place_integer_be(&header[0],  16,  1, format_flags);
	place_integer_be(&header[0],  17,  2, sectors);
	place_string(&header[0],   31, 32, title);
	place_integer_be(&header[0], 103, 2, sector_bytes / 256);

	/* path descriptor options */
	place_integer_be(&header[0], 0x3f+0x00, 1, 1); /* device class */
	place_integer_be(&header[0], 0x3f+0x01, 1, 1); /* drive number */
	place_integer_be(&header[0], 0x3f+0x03, 1, 0x20); /* device type */
	place_integer_be(&header[0], 0x3f+0x04, 1, 1); /* density capability */
	place_integer_be(&header[0], 0x3f+0x05, 2, tracks); /* number of tracks */
	place_integer_be(&header[0], 0x3f+0x07, 1, heads); /* number of sides */
	place_integer_be(&header[0], 0x3f+0x09, 2, sectors); /* sectors per track */
	place_integer_be(&header[0], 0x3f+0x0b, 2, sectors); /* sectors on track zero */
	place_integer_be(&header[0], 0x3f+0x0d, 1, 3); /* sector interleave factor */
	place_integer_be(&header[0], 0x3f+0x0e, 1, 8); /* default sectors per allocation */

	err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id, 0, &header[0], sector_bytes, 0);    /* TODO: pass ddam argument from imgtool */
	if (err)
		goto done;

	total_allocated_sectors = 1 + allocation_bitmap_lsns + 1 + 7;

	for (i = 0; i < allocation_bitmap_lsns; i++)
	{
		memset(&header[0], 0x00, sector_bytes);

		if (total_allocated_sectors > (8 * 256))
		{
			memset(&header[0], 0xff, sector_bytes);
			total_allocated_sectors -= (8 * 256);
		}
		else if (total_allocated_sectors > 1 )
		{
			int offset;
			UINT8 mask;

			while( total_allocated_sectors >= 0 )
			{
				offset = total_allocated_sectors / 8;
				mask = 1 << (7 - ( total_allocated_sectors % 8 ) );

				header[offset] |= mask;
				total_allocated_sectors--;
			}
		}

		err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 1 + i, 0, &header[0], sector_bytes, 0);    /* TODO: pass ddam argument from imgtool */
		if (err)
			goto done;
	}

	memset(&header[0], 0, sector_bytes);
	header[0x00] = 0xBF;
	header[0x01] = 0x00;
	header[0x02] = 0x00;
	header[0x03] = (UINT8) ltime->tm_year;
	header[0x04] = (UINT8) ltime->tm_mon + 1;
	header[0x05] = (UINT8) ltime->tm_mday;
	header[0x06] = (UINT8) ltime->tm_hour;
	header[0x07] = (UINT8) ltime->tm_min;
	header[0x08] = 0x02;
	header[0x09] = 0x00;
	header[0x0A] = 0x00;
	header[0x0B] = 0x00;
	header[0x0C] = 0x40;
	header[0x0D] = (UINT8) (ltime->tm_year % 100);
	header[0x0E] = (UINT8) ltime->tm_mon;
	header[0x0F] = (UINT8) ltime->tm_mday;
	place_integer_be(&header[0], 0x10, 3, 1 + allocation_bitmap_lsns + 1);
	place_integer_be(&header[0], 0x13, 2, 8);

	err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 1 + allocation_bitmap_lsns, 0, &header[0], sector_bytes, 0);   /* TODO: pass ddam argument from imgtool */
	if (err)
		goto done;

	memset(&header[0], 0, sector_bytes);
	header[0x00] = 0x2E;
	header[0x01] = 0xAE;
	header[0x1F] = 1 + allocation_bitmap_lsns;
	header[0x20] = 0xAE;
	header[0x3F] = 1 + allocation_bitmap_lsns;
	err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 2 + allocation_bitmap_lsns, 0, &header[0], sector_bytes, 0);   /* TOOD: pass ddam argument from imgtool */
	if (err)
		goto done;

done:
	return err;
}
Exemple #30
0
static imgtoolerr_t os9_diskimage_open(imgtool_image *image, imgtool_stream *stream)
{
	imgtoolerr_t err;
	floperr_t ferr;
	os9_diskinfo *info;
	UINT32 track_size_in_sectors, i; //, attributes;
	UINT8 header[256];
	UINT32 allocation_bitmap_lsns;
	UINT8 b, mask;

	info = os9_get_diskinfo(image);

	ferr = floppy_read_sector(imgtool_floppy(image), 0, 0, 1, 0, header, sizeof(header));
	if (ferr)
		return imgtool_floppy_error(ferr);

	info->total_sectors             = pick_integer_be(header,   0, 3);
	track_size_in_sectors           = pick_integer_be(header,   3, 1);
	info->allocation_bitmap_bytes   = pick_integer_be(header,   4, 2);
	info->cluster_size              = pick_integer_be(header,   6, 2);
	info->root_dir_lsn              = pick_integer_be(header,   8, 3);
	info->owner_id                  = pick_integer_be(header,  11, 2);
//  attributes                      =
	pick_integer_be(header,  13, 1);
	info->disk_id                   = pick_integer_be(header,  14, 2);
	info->format_flags              = pick_integer_be(header,  16, 1);
	info->sectors_per_track         = pick_integer_be(header,  17, 2);
	info->bootstrap_lsn             = pick_integer_be(header,  21, 3);
	info->bootstrap_size            = pick_integer_be(header,  24, 2);
	info->sector_size               = pick_integer_be(header, 104, 2);

	info->sides                 = (info->format_flags & 0x01) ? 2 : 1;
	info->double_density        = (info->format_flags & 0x02) ? 1 : 0;
	info->double_track          = (info->format_flags & 0x04) ? 1 : 0;
	info->quad_track_density    = (info->format_flags & 0x08) ? 1 : 0;
	info->octal_track_density   = (info->format_flags & 0x10) ? 1 : 0;

	pick_string(header, 31, 32, info->name);

	if (info->sector_size == 0)
		info->sector_size = 256;

	/* does the root directory and allocation bitmap collide? */
	allocation_bitmap_lsns = (info->allocation_bitmap_bytes + info->sector_size - 1) / info->sector_size;
	if (1 + allocation_bitmap_lsns > info->root_dir_lsn)
		return IMGTOOLERR_CORRUPTIMAGE;

	/* is the allocation bitmap too big? */
	info->allocation_bitmap = (UINT8*)imgtool_image_malloc(image, info->allocation_bitmap_bytes);
	if (!info->allocation_bitmap)
		return IMGTOOLERR_OUTOFMEMORY;
	memset(info->allocation_bitmap, 0, info->allocation_bitmap_bytes);

	/* sectors per track and track size don't jive? */
	if (info->sectors_per_track != track_size_in_sectors)
		return IMGTOOLERR_CORRUPTIMAGE;

	/* zero sectors per track? */
	if (info->sectors_per_track == 0)
		return IMGTOOLERR_CORRUPTIMAGE;

	/* do we have an odd number of sectors? */
	if (info->total_sectors % info->sectors_per_track)
		return IMGTOOLERR_CORRUPTIMAGE;

	/* read the allocation bitmap */
	for (i = 0; i < allocation_bitmap_lsns; i++)
	{
		err = os9_read_lsn(image, 1 + i, 0, &info->allocation_bitmap[i * info->sector_size],
			MIN(info->allocation_bitmap_bytes - (i * info->sector_size), info->sector_size));
		if (err)
			return err;
	}

	/* check to make sure that the allocation bitmap and root sector are reserved */
	for (i = 0; i <= allocation_bitmap_lsns; i++)
	{
		b = info->allocation_bitmap[i / 8];
		mask = 1 << (7 - (i % 8));
		if ((b & mask) == 0)
			return IMGTOOLERR_CORRUPTIMAGE;
	}

	return IMGTOOLERR_SUCCESS;
}