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; }
/* Initialize the hardware-level drive emulation (should be called at least once before anything else). Return 0 on success, -1 on error. */ int drive_init(void) { unsigned int dnr; drive_t *drive; if (rom_loaded) { return 0; } drive_init_was_called = 1; driverom_init(); drive_image_init(); drive_log = log_open("Drive"); for (dnr = 0; dnr < DRIVE_NUM; dnr++) { char *logname; drive = drive_context[dnr]->drive; logname = lib_msprintf("Drive %i", dnr + 8); drive->log = log_open(logname); lib_free(logname); drive_clk[dnr] = 0L; drive->clk = &drive_clk[dnr]; drive->mynumber = dnr; } if (driverom_load_images() < 0) { resources_set_int("Drive8Type", DRIVE_TYPE_NONE); resources_set_int("Drive9Type", DRIVE_TYPE_NONE); resources_set_int("Drive10Type", DRIVE_TYPE_NONE); resources_set_int("Drive11Type", DRIVE_TYPE_NONE); return -1; } log_message(drive_log, "Finished loading ROM images."); rom_loaded = 1; drive_overflow_init(); for (dnr = 0; dnr < DRIVE_NUM; dnr++) { drive = drive_context[dnr]->drive; machine_drive_port_default(drive_context[dnr]); if (drive_check_type(drive->type, dnr) < 1) { resources_set_int_sprintf("Drive%iType", DRIVE_TYPE_NONE, dnr + 8); } machine_drive_rom_setup_image(dnr); } for (dnr = 0; dnr < DRIVE_NUM; dnr++) { drive = drive_context[dnr]->drive; drive->gcr = gcr_create_image(); drive->p64 = lib_calloc(1, sizeof(TP64Image)); P64ImageCreate(drive->p64); drive->byte_ready_level = 1; drive->byte_ready_edge = 1; drive->GCR_dirty_track = 0; drive->GCR_write_value = 0x55; drive->GCR_track_start_ptr = NULL; drive->GCR_current_track_size = 0; drive->attach_clk = (CLOCK)0; drive->detach_clk = (CLOCK)0; drive->attach_detach_clk = (CLOCK)0; drive->old_led_status = 0; drive->old_half_track = 0; drive->side = 0; drive->GCR_image_loaded = 0; drive->P64_image_loaded = 0; drive->P64_dirty = 0; drive->read_only = 0; drive->clock_frequency = 1; drive->led_last_change_clk = *(drive->clk); drive->led_last_uiupdate_clk = *(drive->clk); drive->led_active_ticks = 0; rotation_reset(drive); /* Position the R/W head on the directory track. */ drive_set_half_track(36, 0, drive); drive_set_active_led_color(drive->type, dnr); } for (dnr = 0; dnr < DRIVE_NUM; dnr++) { drive = drive_context[dnr]->drive; driverom_initialize_traps(drive); drivesync_clock_frequency(drive->type, drive); rotation_init((drive->clock_frequency == 2) ? 1 : 0, dnr); if (drive->type == DRIVE_TYPE_2000 || drive->type == DRIVE_TYPE_4000) { drivecpu65c02_init(drive_context[dnr], drive->type); } else { drivecpu_init(drive_context[dnr], drive->type); } /* Make sure the sync factor is acknowledged correctly. */ drivesync_factor(drive_context[dnr]); /* Make sure the traps are moved as needed. */ if (drive->enable) { drive_enable(drive_context[dnr]); } } return 0; }