int fsimage_gcr_read_sector(const disk_image_t *image, BYTE *buf, const disk_addr_t *dadr) { fdc_err_t rf; if (dadr->track > image->tracks) { log_error(fsimage_gcr_log, "Track %i out of bounds. Cannot read GCR track.", dadr->track); return -1; } if (image->gcr == NULL) { disk_track_t raw; if (fsimage_gcr_read_track(image, dadr->track, &raw) < 0) { return -1; } if (raw.data == NULL) { return CBMDOS_IPE_NOT_READY; } rf = gcr_read_sector(&raw, buf, (BYTE)dadr->sector); lib_free(raw.data); } else { rf = gcr_read_sector(&image->gcr->tracks[(dadr->track * 2) - 2], buf, (BYTE)dadr->sector); } if (rf != CBMDOS_FDC_ERR_OK) { log_error(fsimage_gcr_log, "Cannot find track: %i sector: %i within GCR image.", dadr->track, dadr->sector); switch (rf) { 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_NOT_READY; } } return CBMDOS_IPE_OK; }
int fsimage_p64_read_sector(disk_image_t *image, BYTE *buf, unsigned int track, unsigned int sector) { unsigned int max_track_length = NUM_MAX_MEM_BYTES_TRACK; BYTE *gcr_data; BYTE *gcr_track_start_ptr; int gcr_track_size, gcr_current_track_size; if (track > 42) { log_error(fsimage_p64_log, "Track %i out of bounds. Cannot read P64 track.", track); return -1; } gcr_data = (BYTE*) lib_malloc(max_track_length); if (fsimage_p64_read_track(image, track, gcr_data, &gcr_track_size) < 0) { log_error(fsimage_p64_log, "Cannot read track %i from P64 image.", track); lib_free(gcr_data); return -1; } gcr_track_start_ptr = gcr_data; gcr_current_track_size = gcr_track_size; if (gcr_read_sector(gcr_track_start_ptr, gcr_current_track_size, buf, track, sector) < 0) { log_error(fsimage_p64_log, "Cannot find track: %i sector: %i within P64 image.", track, sector); lib_free(gcr_data); return -1; } lib_free(gcr_data); return 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; }
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; } }