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)); } } }
/* 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; drive->drive_ram_expand2 = NULL; drive->drive_ram_expand4 = NULL; drive->drive_ram_expand6 = NULL; drive->drive_ram_expand8 = NULL; drive->drive_ram_expanda = NULL; 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); drive->rtc_offset = (time_t)0; /* TODO: offset */ drive->ds1216 = ds1216e_init(&drive->rtc_offset); drive->ds1216->hours12 = 1; } 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 = drive->gcr->data; 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); drive_image_init_track_size_d64(drive); /* Position the R/W head on the directory track. */ drive_set_half_track(36, drive); drive_led_color[dnr] = DRIVE_ACTIVE_RED; } for (dnr = 0; dnr < DRIVE_NUM; dnr++) { drive = drive_context[dnr]->drive; driverom_initialize_traps(drive, 1); 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; }
/* 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; driverom_init(); drive_image_init(); for (dnr = 0; dnr < DRIVE_NUM; dnr++) { char *logname; drive = drive_context[dnr]->drive; logname = lib_msprintf("Drive %i", dnr + 8); 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); return -1; } #ifdef CELL_DEBUG printf("INFO: Finished loading ROM images.\n"); #endif rom_loaded = 1; drive_overflow_init(); for (dnr = 0; dnr < DRIVE_NUM; dnr++) { drive = drive_context[dnr]->drive; drive->drive_ram_expand2 = NULL; drive->drive_ram_expand4 = NULL; drive->drive_ram_expand6 = NULL; drive->drive_ram_expand8 = NULL; drive->drive_ram_expanda = NULL; 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->byte_ready_level = 1; drive->byte_ready_edge = 1; drive->GCR_dirty_track = 0; drive->GCR_write_value = 0x55; drive->GCR_track_start_ptr = drive->gcr->data; 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->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); drive_image_init_track_size_d64(drive); /* Position the R/W head on the directory track. */ drive_set_half_track(36, drive); drive_led_color[dnr] = DRIVE_ACTIVE_RED; } 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); 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; }