Esempio n. 1
0
int vdrive_bam_allocate_chain(vdrive_t *vdrive, unsigned int t, unsigned int s)
{
    BYTE tmp[256];
    int rc;

    while (t) {
        /* Check for illegal track or sector.  */
        if (disk_image_check_sector(vdrive->image, t, s) < 0) {
            vdrive_command_set_error(vdrive, CBMDOS_IPE_ILLEGAL_TRACK_OR_SECTOR,
                                     s, t);
            return CBMDOS_IPE_ILLEGAL_TRACK_OR_SECTOR;
        }
        if (!vdrive_bam_allocate_sector(vdrive, t, s)) {
            /* The real drive does not seem to catch this error.  */
            vdrive_command_set_error(vdrive, CBMDOS_IPE_NO_BLOCK, s, t);
            return CBMDOS_IPE_NO_BLOCK;
        }
        rc = vdrive_read_sector(vdrive, tmp, t, s);
        if (rc > 0) {
            return rc;
        }
        if (rc < 0) {
            return CBMDOS_IPE_NOT_READY;
        }

        t = (int)tmp[0];
        s = (int)tmp[1];
    }
    return CBMDOS_IPE_OK;
}
Esempio n. 2
0
int fsimage_write_sector(disk_image_t *image, BYTE *buf, unsigned int track,
                         unsigned int sector)
{
    int sectors;
    long offset;
    fsimage_t *fsimage;

    fsimage = image->media.fsimage;

    if (fsimage->fd == NULL) {
        log_error(fsimage_log, "Attempt to write without disk image.");
        return -1;
    }

    if (image->read_only != 0) {
        log_error(fsimage_log, "Attempt to write to read-only disk image.");
        return -1;
    }

    sectors = disk_image_check_sector(image, track, sector);

    switch (image->type) {
      case DISK_IMAGE_TYPE_D64:
      case DISK_IMAGE_TYPE_D67:
      case DISK_IMAGE_TYPE_D71:
      case DISK_IMAGE_TYPE_D81:
      case DISK_IMAGE_TYPE_D80:
      case DISK_IMAGE_TYPE_D82:
      case DISK_IMAGE_TYPE_X64:
        if (sectors < 0) {
            log_error(fsimage_log, "Track: %i, Sector: %i out of bounds.",
                      track, sector);
            return -1;
        }
        offset = sectors << 8;

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

        fseek(fsimage->fd, offset, SEEK_SET);

        if (fwrite((char *)buf, 256, 1, fsimage->fd) < 1) {
            log_error(fsimage_log, "Error writing T:%i S:%i to disk image.",
                      track, sector);
            return -1;
        }

        /* Make sure the stream is visible to other readers.  */
        fflush(fsimage->fd);
        break;
      case DISK_IMAGE_TYPE_G64:
        if (fsimage_gcr_write_sector(image, buf, track, sector) < 0)
            return -1;
        break;
      default:
        log_error(fsimage_log, "Unknown disk image.  Cannot write sector.");
        return -1;
    }
    return 0;
}
Esempio n. 3
0
int fsimage_dxx_write_sector(disk_image_t *image, const BYTE *buf, const disk_addr_t *dadr)
{
    int sectors;
    long offset;
    fsimage_t *fsimage;

    fsimage = image->media.fsimage;

    sectors = disk_image_check_sector(image, dadr->track, dadr->sector);

    if (sectors < 0) {
        log_error(fsimage_dxx_log, "Track: %i, Sector: %i out of bounds.",
                  dadr->track, dadr->sector);
        return -1;
    }
    offset = sectors * 256;

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

    if (util_fpwrite(fsimage->fd, buf, 256, offset) < 0) {
        log_error(fsimage_dxx_log, "Error writing T:%i S:%i to disk image.",
                  dadr->track, dadr->sector);
        return -1;
    }
    if (image->gcr != NULL) {
        gcr_write_sector(&image->gcr->tracks[(dadr->track * 2) - 2], buf, (BYTE)dadr->sector);
    }

    if ((fsimage->error_info.map != NULL)
        && (fsimage->error_info.map[sectors] != CBMDOS_FDC_ERR_OK)) {
        offset = fsimage->error_info.len * 256 + sectors;

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

        fsimage->error_info.map[sectors] = CBMDOS_FDC_ERR_OK;
        if (util_fpwrite(fsimage->fd, &fsimage->error_info.map[sectors], 1, offset) < 0) {
            log_error(fsimage_dxx_log, "Error writing T:%i S:%i error info to disk image.",
                      dadr->track, dadr->sector);
        }
    }

    /* Make sure the stream is visible to other readers.  */
    fflush(fsimage->fd);
    return 0;
}
Esempio n. 4
0
void vdrive_dir_free_chain(vdrive_t *vdrive, int t, int s)
{
    BYTE buf[256];

    while (t) {
        /* Check for illegal track or sector.  */
        if (disk_image_check_sector(vdrive->image, t, s) < 0)
            break;

        /* Check if this sector is really allocated.  */
        if (!vdrive_bam_free_sector(vdrive->image_format, vdrive->bam, t, s))
            break;

        /* FIXME: This seems to be redundant.  AB19981124  */
        vdrive_bam_free_sector(vdrive->image_format, vdrive->bam, t, s);
        disk_image_read_sector(vdrive->image, buf, t, s);
        t = (int)buf[0];
        s = (int)buf[1];
    }
}
Esempio n. 5
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;
}
Esempio n. 6
0
int fsimage_dxx_read_sector(const disk_image_t *image, BYTE *buf, const disk_addr_t *dadr)
{
    int sectors;
    long offset;
    fsimage_t *fsimage = image->media.fsimage;
    fdc_err_t rf;

    sectors = disk_image_check_sector(image, dadr->track, dadr->sector);

    if (sectors < 0) {
        log_error(fsimage_dxx_log, "Track %i, Sector %i out of bounds.",
                  dadr->track, dadr->sector);
        return -1;
    }

    offset = sectors * 256;

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

    if (image->gcr == NULL) {
        if (util_fpread(fsimage->fd, buf, 256, offset) < 0) {
            log_error(fsimage_dxx_log,
                      "Error reading T:%i S:%i from disk image.",
                      dadr->track, dadr->sector);
            return -1;
        } else {
            rf = fsimage->error_info.map ? fsimage->error_info.map[sectors] : CBMDOS_FDC_ERR_OK;
        }
    } else {
        rf = gcr_read_sector(&image->gcr->tracks[(dadr->track * 2) - 2], buf, (BYTE)dadr->sector);
    }

    switch (rf) {
        case CBMDOS_FDC_ERR_OK:
            return CBMDOS_IPE_OK;           /* 0 */
        case CBMDOS_FDC_ERR_HEADER:
            return CBMDOS_IPE_READ_ERROR_BNF; /* 20 */
        case CBMDOS_FDC_ERR_SYNC:
            return CBMDOS_IPE_READ_ERROR_SYNC; /* 21 */
        case CBMDOS_FDC_ERR_NOBLOCK:
            return CBMDOS_IPE_READ_ERROR_DATA; /* 22 */
        case CBMDOS_FDC_ERR_DCHECK:
            return CBMDOS_IPE_READ_ERROR_CHK; /* 23 */
        case CBMDOS_FDC_ERR_VERIFY:
            return CBMDOS_IPE_WRITE_ERROR_VER; /* 25 */
        case CBMDOS_FDC_ERR_WPROT:
            return CBMDOS_IPE_WRITE_PROTECT_ON; /* 26 */
        case CBMDOS_FDC_ERR_HCHECK:
            return CBMDOS_IPE_READ_ERROR_BCHK; /* 27 */
        case CBMDOS_FDC_ERR_BLENGTH:
            return CBMDOS_IPE_WRITE_ERROR_BIG; /* 28 */
        case CBMDOS_FDC_ERR_ID:
            return CBMDOS_IPE_DISK_ID_MISMATCH; /* 29 */
        case CBMDOS_FDC_ERR_DRIVE:
            return CBMDOS_IPE_NOT_READY;    /* 74 */
        case CBMDOS_FDC_ERR_DECODE:
            return CBMDOS_IPE_READ_ERROR_GCR; /* 24 */
        default:
            return CBMDOS_IPE_OK;
    }
}
Esempio n. 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;
}
Esempio n. 8
0
int fsimage_read_sector(disk_image_t *image, BYTE *buf, unsigned int track,
                        unsigned int sector)
{
	int sectors;
	long offset;
	fsimage_t *fsimage;

	fsimage = image->media.fsimage;

	if (fsimage->fd == NULL)
	{
		#ifdef CELL_DEBUG
		printf("ERROR: Attempt to read without disk image.\n");
		#endif
		return 74;
	}

	switch (image->type) {
		case DISK_IMAGE_TYPE_D64:
		case DISK_IMAGE_TYPE_D67:
		case DISK_IMAGE_TYPE_D71:
		case DISK_IMAGE_TYPE_D81:
		case DISK_IMAGE_TYPE_D80:
		case DISK_IMAGE_TYPE_D82:
		case DISK_IMAGE_TYPE_X64:
			sectors = disk_image_check_sector(image, track, sector);

			if (sectors < 0)
			{
				#ifdef CELL_DEBUG
				printf("ERROR: Track %i, Sector %i out of bounds.\n", track, sector);
				#endif
				return 66;
			}

			offset = sectors << 8;

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

			fseek(fsimage->fd, offset, SEEK_SET);

			if (fread((char *)buf, 256, 1, fsimage->fd) < 1)
			{
				#ifdef CELL_DEBUG
				printf("ERROR: Error reading T:%i S:%i from disk image.\n", track, sector);
				#endif
				return -1;
			}

			if (fsimage->error_info != NULL) {
				switch (fsimage->error_info[sectors]) {
					case 0x0:
					case 0x1:
						return CBMDOS_IPE_OK;               /* 0 */
					case 0x2:
						return CBMDOS_IPE_READ_ERROR_BNF;   /* 20 */
					case 0x3:
						return CBMDOS_IPE_READ_ERROR_SYNC;  /* 21 */
					case 0x4:
						return CBMDOS_IPE_READ_ERROR_DATA;  /* 22 */
					case 0x5:
						return CBMDOS_IPE_READ_ERROR_CHK;   /* 23 */ 
					case 0x7:
						return CBMDOS_IPE_WRITE_ERROR_VER;  /* 25 */
					case 0x8:
						return CBMDOS_IPE_WRITE_PROTECT_ON; /* 26 */
					case 0x9:
						return CBMDOS_IPE_READ_ERROR_BCHK;  /* 27 */
					case 0xA:
						return CBMDOS_IPE_WRITE_ERROR_BIG;  /* 28 */
					case 0xB:
						return CBMDOS_IPE_DISK_ID_MISMATCH; /* 29 */
					case 0xF:
						return CBMDOS_IPE_NOT_READY;        /* 74 */
					case 0x10:
						return CBMDOS_IPE_READ_ERROR_GCR;   /* 24 */
					default:
						return 0;
				}
			}
			break;
		case DISK_IMAGE_TYPE_G64:
			if (fsimage_gcr_read_sector(image, buf, track, sector) < 0)
				return -1;
			break;
		default:
			#ifdef CELL_DEBUG
			printf("ERROR: Unknown disk image type %i.  Cannot read sector.", image->type);
			#endif
			return -1;
	}
	return 0;
}