void drive_set_last_read(unsigned int track, unsigned int sector, BYTE *buffer, struct drive_context_s *drv) { drive_t *drive; int side = 0; drive = drv->drive; drive_gcr_data_writeback(drive); if (drive->type == DRIVE_TYPE_1570 || drive->type == DRIVE_TYPE_1571 || drive->type == DRIVE_TYPE_1571CR) { if (track > 35) { track -= 35; side = 1; } } drive_set_half_track(track * 2, side, drive); if (drive->type == DRIVE_TYPE_1540 || drive->type == DRIVE_TYPE_1541 || drive->type == DRIVE_TYPE_1541II || drive->type == DRIVE_TYPE_1570 || drive->type == DRIVE_TYPE_1571 || drive->type == DRIVE_TYPE_1571CR) { memcpy(&(drv->drive->drive_ram[0x0400]), buffer, 256); } }
/* Increment the head position by `step' half-tracks. Valid values for `step' are `+1' and `-1'. */ void drive_move_head(int step, drive_t *drive) { drive_gcr_data_writeback(drive); if (drive->type == DRIVE_TYPE_1571 || drive->type == DRIVE_TYPE_1571CR) { if (drive->current_half_track + step == 71) return; } drive_set_half_track(drive->current_half_track + step, drive); }
/* Attach a disk image to the true drive emulation. */ int drive_image_attach(disk_image_t *image, unsigned int unit) { unsigned int dnr; drive_t *drive; if (unit < 8 || unit >= 8 + DRIVE_NUM) { return -1; } dnr = unit - 8; drive = drive_context[dnr]->drive; if (drive_check_image_format(image->type, dnr) < 0) { return -1; } drive->read_only = image->read_only; drive->attach_clk = drive_clk[dnr]; if (drive->detach_clk > (CLOCK)0) { drive->attach_detach_clk = drive_clk[dnr]; } drive->ask_extend_disk_image = 1; switch (image->type) { case DISK_IMAGE_TYPE_D64: case DISK_IMAGE_TYPE_D67: case DISK_IMAGE_TYPE_D71: case DISK_IMAGE_TYPE_G64: case DISK_IMAGE_TYPE_X64: case DISK_IMAGE_TYPE_P64: disk_image_attach_log(image, driveimage_log, unit); break; default: return -1; } drive->image = image; drive->image->gcr = drive->gcr; drive->image->p64 = (void*)drive->p64; if (disk_image_read_image(drive->image) < 0) { drive->image = NULL; return -1; } if (drive->image->type == DISK_IMAGE_TYPE_P64) { drive->P64_image_loaded = 1; drive->P64_dirty = 0; } else { drive->GCR_image_loaded = 1; } drive->complicated_image_loaded = (drive->image->type == DISK_IMAGE_TYPE_P64 || drive->image->type == DISK_IMAGE_TYPE_G64); drive_set_half_track(drive->current_half_track, drive->side, drive); return 0; }
/* Detach a disk image from the true drive emulation. */ int drive_image_detach(disk_image_t *image, unsigned int unit) { unsigned int dnr, i; drive_t *drive; if (unit < 8 || unit >= 8 + DRIVE_NUM) { return -1; } dnr = unit - 8; drive = drive_context[dnr]->drive; if (drive->image != NULL) { switch (image->type) { case DISK_IMAGE_TYPE_D64: case DISK_IMAGE_TYPE_D67: case DISK_IMAGE_TYPE_D71: case DISK_IMAGE_TYPE_G64: case DISK_IMAGE_TYPE_P64: case DISK_IMAGE_TYPE_X64: disk_image_detach_log(image, driveimage_log, unit); break; default: return -1; } } if (drive->P64_image_loaded && drive->P64_dirty) { drive->P64_dirty = 0; if (disk_image_write_p64_image(drive->image) < 0) { log_error(drive->log, "Cannot write disk image back."); } } else { drive_gcr_data_writeback(drive); } for (i = 0; i < MAX_GCR_TRACKS; i++) { if (drive->gcr->tracks[i].data) { lib_free(drive->gcr->tracks[i].data); drive->gcr->tracks[i].data = NULL; drive->gcr->tracks[i].size = 0; } } drive->detach_clk = drive_clk[dnr]; drive->GCR_image_loaded = 0; drive->P64_image_loaded = 0; drive->read_only = 0; drive->image = NULL; drive_set_half_track(drive->current_half_track, drive->side, drive); return 0; }
int drive_snapshot_read_module(snapshot_t *s) { BYTE major_version, minor_version; int i; snapshot_module_t *m; char snap_module_name[] = "DRIVE"; DWORD rotation_table_ptr[DRIVE_NUM]; CLOCK attach_clk[DRIVE_NUM]; CLOCK detach_clk[DRIVE_NUM]; CLOCK attach_detach_clk[DRIVE_NUM]; int drive_true_emulation; int sync_factor; drive_t *drive; int dummy; int half_track[DRIVE_NUM]; m = snapshot_module_open(s, snap_module_name, &major_version, &minor_version); if (m == NULL) { /* If this module is not found true emulation is off. */ resources_set_int("DriveTrueEmulation", 0); return 0; } drive_gcr_data_writeback_all(); if (major_version > DRIVE_SNAP_MAJOR || minor_version > DRIVE_SNAP_MINOR) { log_error(drive_snapshot_log, "Snapshot module version (%d.%d) newer than %d.%d.", major_version, minor_version, DRIVE_SNAP_MAJOR, DRIVE_SNAP_MINOR); } /* If this module exists true emulation is enabled. */ /* XXX drive_true_emulation = 1 */ resources_set_int("DriveTrueEmulation", 1); if (SMR_DW_INT(m, &sync_factor) < 0) { snapshot_module_close(m); return -1; } /* TODO: NUM_DRIVES drives instead of 2 */ for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; /* Partially read 1.0 snapshots */ if (major_version == 1 && minor_version == 0) { if (0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_DW_INT(m, &dummy) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_B_INT(m, &dummy) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &dummy) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 ) { snapshot_module_close(m); return -1; } /* Partially read 1.1 snapshots */ } else if (major_version == 1 && minor_version == 1) { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 ) { snapshot_module_close(m); return -1; } /* Partially read 1.2 snapshots */ } else if (major_version == 1 && minor_version == 2) { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 || SMR_DW(m, &(drive->snap_speed_zone)) < 0 || SMR_DW(m, &(drive->snap_ue7_dcba)) < 0 || SMR_DW(m, &(drive->snap_ue7_counter)) < 0 || SMR_DW(m, &(drive->snap_uf4_counter)) < 0 || SMR_DW(m, &(drive->snap_fr_randcount)) < 0 || SMR_DW(m, &(drive->snap_filter_counter)) < 0 || SMR_DW(m, &(drive->snap_filter_state)) < 0 || SMR_DW(m, &(drive->snap_filter_last_state)) < 0 || SMR_DW(m, &(drive->snap_write_flux)) < 0 || SMR_DW(m, &(drive->snap_PulseHeadPosition)) < 0 || SMR_DW(m, &(drive->snap_xorShift32)) < 0 ) { snapshot_module_close(m); return -1; } } else if (major_version == 1 && minor_version == 3) { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 || SMR_DW(m, &(drive->snap_speed_zone)) < 0 || SMR_DW(m, &(drive->snap_ue7_dcba)) < 0 || SMR_DW(m, &(drive->snap_ue7_counter)) < 0 || SMR_DW(m, &(drive->snap_uf4_counter)) < 0 || SMR_DW(m, &(drive->snap_fr_randcount)) < 0 || SMR_DW(m, &(drive->snap_filter_counter)) < 0 || SMR_DW(m, &(drive->snap_filter_state)) < 0 || SMR_DW(m, &(drive->snap_filter_last_state)) < 0 || SMR_DW(m, &(drive->snap_write_flux)) < 0 || SMR_DW(m, &(drive->snap_PulseHeadPosition)) < 0 || SMR_DW(m, &(drive->snap_xorShift32)) < 0 || SMR_DW(m, &(drive->snap_so_delay)) < 0 ) { snapshot_module_close(m); return -1; } } else { if (0 || SMR_DW(m, &(attach_clk[i])) < 0 || SMR_B_INT(m, (int *)&(drive->byte_ready_level)) < 0 || SMR_B_INT(m, &(drive->clock_frequency)) < 0 || SMR_W_INT(m, &half_track[i]) < 0 || SMR_DW(m, &(detach_clk[i])) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B(m, (BYTE *)&dummy) < 0 || SMR_B_INT(m, &(drive->extend_image_policy)) < 0 || SMR_DW_UINT(m, &(drive->GCR_head_offset)) < 0 || SMR_B(m, &(drive->GCR_read)) < 0 || SMR_B(m, &(drive->GCR_write_value)) < 0 || SMR_B_INT(m, &(drive->idling_method)) < 0 || SMR_B_INT(m, &(drive->parallel_cable)) < 0 || SMR_B_INT(m, &(drive->read_only)) < 0 || SMR_DW(m, &rotation_table_ptr[i]) < 0 || SMR_DW_UINT(m, &(drive->type)) < 0 || SMR_DW_UL(m, &(drive->snap_accum)) < 0 || SMR_DW(m, &(drive->snap_rotation_last_clk)) < 0 || SMR_DW_INT(m, &(drive->snap_bit_counter)) < 0 || SMR_DW_INT(m, &(drive->snap_zero_count)) < 0 || SMR_W_INT(m, &(drive->snap_last_read_data)) < 0 || SMR_B(m, &(drive->snap_last_write_data)) < 0 || SMR_DW_INT(m, &(drive->snap_seed)) < 0 || SMR_DW(m, &(drive->snap_speed_zone)) < 0 || SMR_DW(m, &(drive->snap_ue7_dcba)) < 0 || SMR_DW(m, &(drive->snap_ue7_counter)) < 0 || SMR_DW(m, &(drive->snap_uf4_counter)) < 0 || SMR_DW(m, &(drive->snap_fr_randcount)) < 0 || SMR_DW(m, &(drive->snap_filter_counter)) < 0 || SMR_DW(m, &(drive->snap_filter_state)) < 0 || SMR_DW(m, &(drive->snap_filter_last_state)) < 0 || SMR_DW(m, &(drive->snap_write_flux)) < 0 || SMR_DW(m, &(drive->snap_PulseHeadPosition)) < 0 || SMR_DW(m, &(drive->snap_xorShift32)) < 0 || SMR_DW(m, &(drive->snap_so_delay)) < 0 || SMR_DW(m, &(drive->snap_cycle_index)) < 0 || SMR_DW(m, &(drive->snap_ref_advance)) < 0 || SMR_DW(m, &(drive->snap_req_ref_cycles)) < 0 ) { snapshot_module_close(m); return -1; } } } /* this one is new, so don't test so stay compatible with old snapshots */ for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; SMR_DW(m, &(attach_detach_clk[i])); } /* these are even newer */ for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; SMR_B_INT(m, (int *)&(drive->byte_ready_edge)); SMR_B_INT(m, (int *)&(drive->byte_ready_active)); } snapshot_module_close(m); m = NULL; rotation_table_set(rotation_table_ptr); drive = drive_context[0]->drive; switch (drive->type) { case DRIVE_TYPE_1540: case DRIVE_TYPE_1541: case DRIVE_TYPE_1541II: case DRIVE_TYPE_1551: case DRIVE_TYPE_1570: case DRIVE_TYPE_1571: case DRIVE_TYPE_1571CR: case DRIVE_TYPE_1581: case DRIVE_TYPE_2000: case DRIVE_TYPE_4000: case DRIVE_TYPE_2031: case DRIVE_TYPE_1001: case DRIVE_TYPE_2040: case DRIVE_TYPE_3040: case DRIVE_TYPE_4040: case DRIVE_TYPE_8050: case DRIVE_TYPE_8250: drive->enable = 1; machine_drive_rom_setup_image(0); drivemem_init(drive_context[0], drive->type); resources_set_int("Drive8IdleMethod", drive->idling_method); driverom_initialize_traps(drive); drive_set_active_led_color(drive->type, 0); machine_bus_status_drivetype_set(8, 1); break; case DRIVE_TYPE_NONE: drive_disable(drive_context[0]); machine_bus_status_drivetype_set(8, 0); break; default: return -1; } drive = drive_context[1]->drive; switch (drive->type) { case DRIVE_TYPE_1540: case DRIVE_TYPE_1541: case DRIVE_TYPE_1541II: case DRIVE_TYPE_1551: case DRIVE_TYPE_1570: case DRIVE_TYPE_1571: case DRIVE_TYPE_1581: case DRIVE_TYPE_2000: case DRIVE_TYPE_4000: case DRIVE_TYPE_2031: case DRIVE_TYPE_1001: /* drive 1 does not allow dual disk drive */ drive->enable = 1; machine_drive_rom_setup_image(1); drivemem_init(drive_context[1], drive->type); resources_set_int("Drive9IdleMethod", drive->idling_method); driverom_initialize_traps(drive); drive_set_active_led_color(drive->type, 1); machine_bus_status_drivetype_set(9, 1); break; case DRIVE_TYPE_NONE: case DRIVE_TYPE_8050: case DRIVE_TYPE_8250: drive_disable(drive_context[1]); machine_bus_status_drivetype_set(9, 0); break; default: return -1; } /* Clear parallel cable before undumping parallel port values. */ for (i = 0; i < DRIVE_PC_NUM; i++) { parallel_cable_drive_write(i, 0xff, PARALLEL_WRITE, 0); parallel_cable_drive_write(i, 0xff, PARALLEL_WRITE, 1); } for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; if (drive->enable) { if (drive->type == DRIVE_TYPE_2000 || drive->type == DRIVE_TYPE_4000) { if (drivecpu65c02_snapshot_read_module(drive_context[i], s) < 0) { return -1; } } else { if (drivecpu_snapshot_read_module(drive_context[i], s) < 0) { return -1; } } if (machine_drive_snapshot_read(drive_context[i], s) < 0) { return -1; } } } if (drive_snapshot_read_image_module(s, 0) < 0 || drive_snapshot_read_gcrimage_module(s, 0) < 0 || drive_snapshot_read_p64image_module(s, 0) < 0) { return -1; } if (drive_snapshot_read_image_module(s, 1) < 0 || drive_snapshot_read_gcrimage_module(s, 1) < 0 || drive_snapshot_read_p64image_module(s, 1) < 0) { return -1; } if (driverom_snapshot_read(s, drive_context[0]->drive) < 0) { return -1; } if (driverom_snapshot_read(s, drive_context[1]->drive) < 0) { return -1; } for (i = 0; i < 2; i++) { drive = drive_context[i]->drive; if (drive->type != DRIVE_TYPE_NONE) { drive_enable(drive_context[i]); drive->attach_clk = attach_clk[i]; drive->detach_clk = detach_clk[i]; drive->attach_detach_clk = attach_detach_clk[i]; } } for (i = 0; i < 2; i++) { int side = 0; drive = drive_context[i]->drive; if (drive->type == DRIVE_TYPE_1570 || drive->type == DRIVE_TYPE_1571 || drive->type == DRIVE_TYPE_1571CR) { if (half_track[i] > (DRIVE_HALFTRACKS_1571 + 1)) { side = 1; half_track[i] -= DRIVE_HALFTRACKS_1571; } } drive_set_half_track(half_track[i], side, drive); resources_set_int("MachineVideoStandard", sync_factor); } /* stop currently active drive sounds (bug #3539422) * FIXME: when the drive sound emulation becomes more precise, we might * want/need to save a snapshot of its current state too */ drive_sound_stop(); iec_update_ports_embedded(); drive_update_ui_status(); resources_get_int("DriveTrueEmulation", &drive_true_emulation); if (vdrive_snapshot_module_read(s, drive_true_emulation ? 10 : 8) < 0) { return -1; } return 0; }
/* Increment the head position by `step' half-tracks. Valid values for `step' are `+1', '+2' and `-1'. */ void drive_move_head(int step, drive_t *drive) { drive_gcr_data_writeback(drive); drive_sound_head(drive->current_half_track, step, drive->mynumber); drive_set_half_track(drive->current_half_track + step, drive->side, drive); }
/* 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; }
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; 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; }