Example #1
0
static int fsimage_create_p64(disk_image_t *image)
{
    TP64MemoryStream P64MemoryStreamInstance;
    TP64Image P64Image;
    BYTE gcr_track[7928], *gcrptr;
    unsigned int track, sector;
    fsimage_t *fsimage;
    int rc = -1;

    fsimage = image->media.fsimage;

    P64ImageCreate(&P64Image);

    for (track = 0; track < MAX_TRACKS_1541; track++) {
        const int raw_track_size[4] = { 6250, 6666, 7142, 7692 };

        memset(&gcr_track[0], 0x55, 7928);
        gcrptr = &gcr_track[0];

        for (sector = 0;
        sector < disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track + 1);
        sector++) {
            BYTE chksum, id[2], rawdata[260];
            int i;

            id[0] = id[1] = 0xa0;
            memset(rawdata, 0, 260);
            rawdata[0] = 7;
            chksum = rawdata[1];
            for (i = 1; i < 256; i++) {
                chksum ^= rawdata[i + 1];
            }
            rawdata[257] = chksum;

            gcr_convert_sector_to_GCR(rawdata, gcrptr, track + 1, sector,
                                      id[0], id[1], 0);
            gcrptr += 360;
        }


        P64PulseStreamConvertFromGCR(&P64Image.PulseStreams[(track + 1) << 1], (void*)&gcr_track[0], raw_track_size[disk_image_speed_map_1541(track)] << 3);

    }

    P64MemoryStreamCreate(&P64MemoryStreamInstance);
    P64MemoryStreamClear(&P64MemoryStreamInstance);
    if (P64ImageWriteToStream(&P64Image,&P64MemoryStreamInstance)) {
        if (fwrite(P64MemoryStreamInstance.Data, P64MemoryStreamInstance.Size, 1, fsimage->fd) < 1) {
          log_error(createdisk_log, "Cannot write image data.");
          rc = -1;
        } else {
          rc = 0;
        }
    }
    P64MemoryStreamDestroy(&P64MemoryStreamInstance);

    P64ImageDestroy(&P64Image);

    return rc;
}
Example #2
0
int vdrive_get_max_sectors(unsigned int type, unsigned int track)
{
    switch (type) {
      case VDRIVE_IMAGE_FORMAT_1541:
        return disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track);
      case VDRIVE_IMAGE_FORMAT_2040:
        return disk_image_sector_per_track(DISK_IMAGE_TYPE_D67, track);
      case VDRIVE_IMAGE_FORMAT_1571:
        return disk_image_sector_per_track(DISK_IMAGE_TYPE_D71, track);
      case VDRIVE_IMAGE_FORMAT_8050:
        return disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track);
      case VDRIVE_IMAGE_FORMAT_1581:
        return 40;
      case VDRIVE_IMAGE_FORMAT_8250:
        if (track <= NUM_TRACKS_8250 / 2) {
            return disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track);
        } else {
            return disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track
                                               - (NUM_TRACKS_8250 / 2));
        }
      default:
        log_message(vdrive_log,
                    "Unknown disk type %i.  Cannot calculate max sectors",
                    type);

    }
    return -1;
}
Example #3
0
int vdrive_get_max_sectors(unsigned int type, unsigned int track)
{
	switch (type)
	{
		case VDRIVE_IMAGE_FORMAT_1541:
			return disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track);
		case VDRIVE_IMAGE_FORMAT_2040:
			return disk_image_sector_per_track(DISK_IMAGE_TYPE_D67, track);
		case VDRIVE_IMAGE_FORMAT_1571:
			return disk_image_sector_per_track(DISK_IMAGE_TYPE_D71, track);
		case VDRIVE_IMAGE_FORMAT_8050:
			return disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track);
		case VDRIVE_IMAGE_FORMAT_1581:
			return 40;
		case VDRIVE_IMAGE_FORMAT_8250:
			if (track <= NUM_TRACKS_8250 / 2)
				return disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track);
			else
				return disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track - (NUM_TRACKS_8250 / 2));
		default:
			#ifdef CELL_DEBUG
			printf("ERROR: Unknown disk type %i.  Cannot calculate max sectors\n", type);
			#endif
			break;

	}
	return -1;
}
Example #4
0
static void drive_extend_disk_image(drive_t *drive)
{
    int rc;
    unsigned int track, sector;
    BYTE buffer[256];

    drive->image->tracks = EXT_TRACKS_1541;
    memset(buffer, 0, 256);
    for (track = NUM_TRACKS_1541 + 1; track <= EXT_TRACKS_1541; track++) {
        for (sector = 0;
             sector < disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track);
             sector++) {
             rc = disk_image_write_sector(drive->image, buffer, track,
                                          sector);
             if (rc < 0)
                 log_error(drive->log,
                           "Could not update T:%d S:%d.", track, sector);
        }
    }
}
Example #5
0
static void drive_extend_disk_image(drive_t *drive)
{
	int rc;
	unsigned int track, sector;
	BYTE buffer[256];

	drive->image->tracks = EXT_TRACKS_1541;
	memset(buffer, 0, 256);
	for (track = NUM_TRACKS_1541 + 1; track <= EXT_TRACKS_1541; track++)
	{
		for (sector = 0; sector < disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track); sector++)
		{
			rc = disk_image_write_sector(drive->image, buffer, track, sector);

			#ifdef CELL_DEBUG
			if (rc < 0)
				printf("ERROR: Could not update T:%d S:%d.\n", track, sector);
			#endif
		}
	}
}
Example #6
0
int fsimage_dxx_write_half_track(disk_image_t *image, unsigned int half_track,
                                 const disk_track_t *raw)
{
    unsigned int track, sector, max_sector = 0, error_info_created = 0;
    int sectors, res;
    long offset;
    BYTE *buffer;
    fsimage_t *fsimage = image->media.fsimage;
    fdc_err_t rf;

    track = half_track / 2;

    max_sector = disk_image_sector_per_track(image->type, track);
    sectors = disk_image_check_sector(image, track, 0);
    if (sectors < 0) {
        log_error(fsimage_dxx_log, "Track: %i out of bounds.", track);
        return -1;
    }

    if (track > image->tracks) {
        if (fsimage->error_info.map) {
            int newlen = sectors + max_sector;
            fsimage->error_info.map = lib_realloc(fsimage->error_info.map, newlen);
            memset(fsimage->error_info.map + fsimage->error_info.len, 0,
                   newlen - fsimage->error_info.len);
            fsimage->error_info.len = newlen;
            fsimage->error_info.dirty = 1;
        }
        image->tracks = track;
    }

    buffer = lib_calloc(max_sector, 256);
    for (sector = 0; sector < max_sector; sector++) {
        rf = gcr_read_sector(raw, &buffer[sector * 256], (BYTE)sector);
        if (rf != CBMDOS_FDC_ERR_OK) {
            log_error(fsimage_dxx_log,
                      "Could not find data sector of T:%d S:%d.",
                      track, sector);
            if (fsimage->error_info.map == NULL) { /* create map if does not exists */
                int newlen = disk_image_check_sector(image, image->tracks, 0);
                if (newlen >= 0) {
                    newlen += disk_image_sector_per_track(image->type, image->tracks);
                    fsimage->error_info.map = lib_malloc(newlen);
                    memset(fsimage->error_info.map, (BYTE)CBMDOS_FDC_ERR_OK, newlen);
                    fsimage->error_info.len = newlen;
                    fsimage->error_info.dirty = 1;
                    error_info_created = 1;
                }
            }
        }
        if (fsimage->error_info.map != NULL) {
            if (fsimage->error_info.map[sectors + sector] != (BYTE)rf) {
                fsimage->error_info.map[sectors + sector] = (BYTE)rf;
                fsimage->error_info.dirty = 1;
            }
        }
    }
    offset = sectors * 256;

    if (image->type == DISK_IMAGE_TYPE_X64) {
        offset += X64_HEADER_LENGTH;
    }

    if (util_fpwrite(fsimage->fd, buffer, max_sector * 256, offset) < 0) {
        log_error(fsimage_dxx_log, "Error writing T:%i to disk image.",
                  track);
        lib_free(buffer);
        return -1;
    }
    lib_free(buffer);
    if (fsimage->error_info.map) {
        if (fsimage->error_info.dirty) {
            offset = fsimage->error_info.len * 256 + sectors;

            if (image->type == DISK_IMAGE_TYPE_X64) {
                offset += X64_HEADER_LENGTH;
            }

            fsimage->error_info.dirty = 0;
            if (error_info_created) {
                res = util_fpwrite(fsimage->fd, fsimage->error_info.map,
                                   fsimage->error_info.len, fsimage->error_info.len * 256);
            } else {
                res = util_fpwrite(fsimage->fd, fsimage->error_info.map + sectors,
                                   max_sector, offset);
            }
            if (res < 0) {
                log_error(fsimage_dxx_log, "Error writing T:%i error info to disk image.",
                          track);
                return -1;
            }
        }
    }

    /* Make sure the stream is visible to other readers.  */
    fflush(fsimage->fd);
    return 0;
}
Example #7
0
int fsimage_read_dxx_image(const disk_image_t *image)
{
    BYTE buffer[256], *bam_id;
    int gap;
    unsigned int track, sector, track_size;
    gcr_header_t header;
    fdc_err_t rf;
    int double_sided = 0;
    fsimage_t *fsimage = image->media.fsimage;
    unsigned int max_sector;
    BYTE *ptr;
    int half_track;
    int sectors;
    long offset;

    if (image->type == DISK_IMAGE_TYPE_D80
        || image->type == DISK_IMAGE_TYPE_D82) {
        sectors = disk_image_check_sector(image, BAM_TRACK_8050, BAM_SECTOR_8050);
        bam_id = &buffer[BAM_ID_8050];
    } else {
        sectors = disk_image_check_sector(image, BAM_TRACK_1541, BAM_SECTOR_1541);
        bam_id = &buffer[BAM_ID_1541];
    }

    bam_id[0] = bam_id[1] = 0xa0;
    if (sectors >= 0) {
        util_fpread(fsimage->fd, buffer, 256, sectors << 8);
    }
    header.id1 = bam_id[0];
    header.id2 = bam_id[1];

    /* check double sided images */
    double_sided = (image->type == DISK_IMAGE_TYPE_D71) && !(buffer[0x03] & 0x80);

    for (header.track = track = 1; track <= image->max_half_tracks / 2; track++, header.track++) {
        half_track = track * 2 - 2;

        track_size = disk_image_raw_track_size(image->type, track);
        if (image->gcr->tracks[half_track].data == NULL) {
            image->gcr->tracks[half_track].data = lib_malloc(track_size);
        } else if (image->gcr->tracks[half_track].size != (int)track_size) {
            image->gcr->tracks[half_track].data = lib_realloc(image->gcr->tracks[half_track].data, track_size);
        }
        ptr = image->gcr->tracks[half_track].data;
        image->gcr->tracks[half_track].size = track_size;

        if (track <= image->tracks) {
            if (double_sided && track == 36) {
                sectors = disk_image_check_sector(image, BAM_TRACK_1571 + 35, BAM_SECTOR_1571);

                buffer[BAM_ID_1571] = buffer[BAM_ID_1571 + 1] = 0xa0;
                if (sectors >= 0) {
                    util_fpread(fsimage->fd, buffer, 256, sectors << 8);
                }
                header.id1 = buffer[BAM_ID_1571]; /* second side, update id and track */
                header.id2 = buffer[BAM_ID_1571 + 1];
                header.track = 1;
            }

            gap = disk_image_gap_size(image->type, track);

            max_sector = disk_image_sector_per_track(image->type, track);

            /* Clear track to avoid read errors.  */
            memset(ptr, 0x55, track_size);

            for (sector = 0; sector < max_sector; sector++) {
                sectors = disk_image_check_sector(image, track, sector);
                offset = sectors * 256;

                if (image->type == DISK_IMAGE_TYPE_X64) {
                    offset += X64_HEADER_LENGTH;
                }

                if (sectors >= 0) {
                    rf = CBMDOS_FDC_ERR_DRIVE;
                    if (util_fpread(fsimage->fd, buffer, 256, offset) >= 0) {
                        if (fsimage->error_info.map != NULL) {
                            rf = fsimage->error_info.map[sectors];
                        }
                    }
                    header.sector = sector;
                    gcr_convert_sector_to_GCR(buffer, ptr, &header, 9, 5, rf);
                }

                ptr += SECTOR_GCR_SIZE_WITH_HEADER + 9 + gap + 5;
            }
        } else {
            memset(ptr, 0x55, track_size);
        }

        /* Clear odd track */
        half_track++;
        if (image->gcr->tracks[half_track].data) {
            lib_free(image->gcr->tracks[half_track].data);
            image->gcr->tracks[half_track].data = NULL;
            image->gcr->tracks[half_track].size = 0;
        }
    }
    return 0;
}
Example #8
0
static int fsimage_create_gcr(disk_image_t *image)
{
    BYTE gcr_header[12], gcr_track[7930], *gcrptr;
    DWORD gcr_track_p[MAX_TRACKS_1541 * 2];
    DWORD gcr_speed_p[MAX_TRACKS_1541 * 2];
    unsigned int track, sector;
    fsimage_t *fsimage;

    fsimage = image->media.fsimage;

    strcpy((char *)gcr_header, "GCR-1541");

    gcr_header[8] = 0;
    gcr_header[9] = MAX_TRACKS_1541 * 2;
    gcr_header[10] = 7928 % 256;
    gcr_header[11] = 7928 / 256;

    if (fwrite((char *)gcr_header, sizeof(gcr_header), 1, fsimage->fd) < 1) {
        log_error(createdisk_log, "Cannot write GCR header.");
        return -1;
    }

    for (track = 0; track < MAX_TRACKS_1541; track++) {
        gcr_track_p[track * 2] = 12 + MAX_TRACKS_1541 * 16 + track * 7930;
        gcr_track_p[track * 2 + 1] = 0;
        gcr_speed_p[track * 2] = disk_image_speed_map_1541(track);
        gcr_speed_p[track * 2 + 1] = 0;
    }

    if (util_dword_write(fsimage->fd, gcr_track_p, util_arraysize(gcr_track_p)) < 0) {
        log_error(createdisk_log, "Cannot write track header.");
        return -1;
    }
    if (util_dword_write(fsimage->fd, gcr_speed_p, util_arraysize(gcr_speed_p)) < 0) {
        log_error(createdisk_log, "Cannot write speed header.");
        return -1;
    }
    for (track = 0; track < MAX_TRACKS_1541; track++) {
        const int raw_track_size[4] = { 6250, 6666, 7142, 7692 };

        memset(&gcr_track[2], 0x55, 7928);
        gcr_track[0] = raw_track_size[disk_image_speed_map_1541(track)] % 256;
        gcr_track[1] = raw_track_size[disk_image_speed_map_1541(track)] / 256;
        gcrptr = &gcr_track[2];

        for (sector = 0;
        sector < disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track + 1);
        sector++) {
            BYTE chksum, id[2], rawdata[260];
            int i;

            id[0] = id[1] = 0xa0;
            memset(rawdata, 0, 260);
            rawdata[0] = 7;
            chksum = rawdata[1];
            for (i = 1; i < 256; i++)
                chksum ^= rawdata[i + 1];
            rawdata[257] = chksum;

            gcr_convert_sector_to_GCR(rawdata, gcrptr, track + 1, sector,
                                      id[0], id[1], 0);
            gcrptr += 360;
        }
        if (fwrite((char *)gcr_track, sizeof(gcr_track), 1, fsimage->fd) < 1 ) {
            log_error(createdisk_log, "Cannot write track data.");
            return -1;
        }
    }
    return 0;
}
Example #9
0
void drive_gcr_data_writeback(drive_t *drive)
{
    int extend;
    unsigned int half_track, track, sector, max_sector = 0;
    BYTE buffer[260], *offset;

    if (drive->image == NULL) {
        return;
    }

    half_track = drive->current_half_track;
    track = drive->current_half_track / 2;

    if (drive->image->type == DISK_IMAGE_TYPE_P64) {
        return;
    }

    if (!(drive->GCR_dirty_track)) {
        return;
    }

    if (drive->image->type == DISK_IMAGE_TYPE_G64) {
        BYTE *gcr_track_start_ptr;
        unsigned int gcr_current_track_size;

        gcr_current_track_size = drive->gcr->track_size[half_track - 2];

        gcr_track_start_ptr = drive->gcr->data
                              + ((half_track - 2) * drive->gcr->max_track_size);

        disk_image_write_half_track(drive->image, half_track,
                                   gcr_current_track_size,
                                   drive->gcr->speed_zone,
                                   gcr_track_start_ptr);
        drive->GCR_dirty_track = 0;
        return;
    }

    if (drive->image->type == DISK_IMAGE_TYPE_D64
        || drive->image->type == DISK_IMAGE_TYPE_X64) {
        if (track > EXT_TRACKS_1541)
            return;
        max_sector = disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track);
        if (track > drive->image->tracks) {
            switch (drive->extend_image_policy) {
              case DRIVE_EXTEND_NEVER:
                drive->ask_extend_disk_image = 1;
                return;
              case DRIVE_EXTEND_ASK:
                if (drive->ask_extend_disk_image == 1) {
                    extend = ui_extend_image_dialog();
                    if (extend == 0) {
                        drive->ask_extend_disk_image = 0;
                        return;
                    } else {
                        drive_extend_disk_image(drive);
                    }
                } else {
                    return;
                }
                break;
              case DRIVE_EXTEND_ACCESS:
                drive->ask_extend_disk_image = 1;
                drive_extend_disk_image(drive);
                break;
            }
        }
    }

    if (drive->image->type == DISK_IMAGE_TYPE_D71) {
        if (track > MAX_TRACKS_1571)
            return;
        max_sector = disk_image_sector_per_track(DISK_IMAGE_TYPE_D71, track);
    }

    drive->GCR_dirty_track = 0;

    for (sector = 0; sector < max_sector; sector++) {

        offset = gcr_find_sector_header(track, sector,
                                        drive->GCR_track_start_ptr,
                                        drive->GCR_current_track_size);
        if (offset == NULL) {
            log_error(drive->log,
                      "Could not find header of T:%d S:%d.",
                      track, sector);
        } else {
            offset = gcr_find_sector_data(offset,
                                          drive->GCR_track_start_ptr,
                                          drive->GCR_current_track_size);
            if (offset == NULL) {
                log_error(drive->log,
                          "Could not find data sync of T:%d S:%d.",
                          track, sector);
            } else {
                gcr_data_writeback2(buffer, offset, track, sector, drive);
            }
        }
    }
}
Example #10
0
static void drive_image_read_d64_d71(drive_t *drive)
{
	BYTE buffer[260], chksum;
	int i;
	unsigned int track, sector;

	if (!(drive->image))
		return;

	buffer[258] = buffer[259] = 0;

	/* Since the D64/D71 format does not provide the actual track sizes or
	   speed zones, we set them to standard values.  */
	if ((drive->image->type == DISK_IMAGE_TYPE_D64
				|| drive->image->type == DISK_IMAGE_TYPE_D67
				|| drive->image->type == DISK_IMAGE_TYPE_X64)
			&& (drive->type == DRIVE_TYPE_1541
				|| drive->type == DRIVE_TYPE_1541II
				|| drive->type == DRIVE_TYPE_1551
				|| drive->type == DRIVE_TYPE_1570
				|| drive->type == DRIVE_TYPE_2031)) {
		drive_image_init_track_size_d64(drive);
	}
	if (drive->image->type == DISK_IMAGE_TYPE_D71
			|| drive->type == DRIVE_TYPE_1571
			|| drive->type == DRIVE_TYPE_1571CR
			|| drive->type == DRIVE_TYPE_2031) {
		drive_image_init_track_size_d71(drive);
	}

	drive_set_half_track(drive->current_half_track, drive);

	for (track = 1; track <= drive->image->tracks; track++) {
		BYTE *ptr;
		unsigned int max_sector = 0;

		ptr = drive->gcr->data + GCR_OFFSET(track);
		max_sector = disk_image_sector_per_track(drive->image->type,
				track);
		/* Clear track to avoid read errors.  */
		memset(ptr, 0x55, NUM_MAX_BYTES_TRACK);

		for (sector = 0; sector < max_sector; sector++)
		{
			int rc;
			ptr = drive->gcr->data + sector_offset(track, sector,
					max_sector, drive);

			rc = disk_image_read_sector(drive->image, buffer + 1, track,
					sector);

#ifdef CELL_DEBUG
			if (rc < 0) {
				printf("ERROR: Cannot read T:%d S:%d from disk image.\n", track, sector);
				continue;
			}
#endif

			if (rc == 21) {
				ptr = drive->gcr->data + GCR_OFFSET(track);
				memset(ptr, 0x00, NUM_MAX_BYTES_TRACK);
				break;
			}

			buffer[0] = (rc == 22) ? 0xff : 0x07;

			chksum = buffer[1];
			for (i = 2; i < 257; i++)
				chksum ^= buffer[i];
			buffer[257] = (rc == 23) ? chksum ^ 0xff : chksum;
			gcr_convert_sector_to_GCR(buffer, ptr, track, sector,
					drive->diskID1, drive->diskID2,
					(BYTE)(rc));
		}
	}
}
Example #11
0
int fsimage_check_sector(disk_image_t *image, unsigned int track,
                         unsigned int sector)
{
    unsigned int sectors = 0, i;

    if (track < 1)
        return -1;

    switch (image->type) {
      case DISK_IMAGE_TYPE_D64:
      case DISK_IMAGE_TYPE_X64:
        if (track > MAX_TRACKS_1541 || sector
            >= disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track))
            return -1;
        for (i = 1; i < track; i++)
            sectors += disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, i);
        sectors += sector;
        break;
      case DISK_IMAGE_TYPE_D67:
        if (track > MAX_TRACKS_2040 || sector
            >= disk_image_sector_per_track(DISK_IMAGE_TYPE_D67, track))
            return -1;
        for (i = 1; i < track; i++)
            sectors += disk_image_sector_per_track(DISK_IMAGE_TYPE_D67, i);
        sectors += sector;
        break;
      case DISK_IMAGE_TYPE_D71:
        if (track > MAX_TRACKS_1571)
            return -1;
        if (track > NUM_TRACKS_1541) {          /* The second side */
            track -= NUM_TRACKS_1541;
            sectors = NUM_BLOCKS_1541;
        }
        if (sector >= disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track))
            return -1;
        for (i = 1; i < track; i++)
            sectors += disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, i);
        sectors += sector;
        break;
      case DISK_IMAGE_TYPE_D81:
        if (track > MAX_TRACKS_1581 || sector >=  NUM_SECTORS_1581)
            return -1;
        sectors = (track - 1) * NUM_SECTORS_1581 + sector;
        break;
      case DISK_IMAGE_TYPE_D80:
        if (track > MAX_TRACKS_8050 || sector
            >= disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track))
            return -1;
        for (i = 1; i < track; i++)
            sectors += disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, i);
        sectors += sector;
        break;
      case DISK_IMAGE_TYPE_D82:
        if (track > MAX_TRACKS_8250)
            return -1;
        if (track > NUM_TRACKS_8050) {          /* The second side */
            track -= NUM_TRACKS_8050;
            sectors = NUM_BLOCKS_8050;
        }
        if (sector >= disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, track))
            return -1;
        for (i = 1; i < track; i++)
            sectors += disk_image_sector_per_track(DISK_IMAGE_TYPE_D80, i);
        sectors += sector;
        break;
      case DISK_IMAGE_TYPE_G64:
      case DISK_IMAGE_TYPE_P64:
        if (track > image->tracks || track > MAX_TRACKS_1541 || sector
            >= disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, track))
            return -1;
        for (i = 1; i < track; i++)
            sectors += disk_image_sector_per_track(DISK_IMAGE_TYPE_D64, i);
        sectors += sector;
        break;
      case DISK_IMAGE_TYPE_D1M:
        if (track > NUM_TRACKS_1000 || sector > 255
            || (track == NUM_TRACKS_1000 && sector >= NUM_SYS_SECTORS_1000))
            return -1;
        sectors = (track - 1) * 256 + sector;
        break;
      case DISK_IMAGE_TYPE_D2M:
        if (track > NUM_TRACKS_2000 || sector > 255
            || (track == NUM_TRACKS_2000 && sector >= NUM_SYS_SECTORS_2000))
            return -1;
        sectors = (track - 1) * 256 + sector;
        break;
      case DISK_IMAGE_TYPE_D4M:
        if (track > NUM_TRACKS_4000 || sector > 255
            || (track == NUM_TRACKS_4000 && sector >= NUM_SYS_SECTORS_4000))
            return -1;
        sectors = (track - 1) * 256 + sector;
        break;
      default:
        return -1;
    }
    return (int)(sectors);
}