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; }
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; }
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; }
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)); } } }