/* 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; }
static int drive_resources_type(int val, void *param) { unsigned int type, dnr; int busses; drive_t *drive, *drive0; char *rtc_device = NULL; dnr = vice_ptr_to_uint(param); drive = drive_context[dnr]->drive; type = (unsigned int)val; busses = iec_available_busses(); /* if bus for drive type is not allowed, set to default value for bus */ if (!drive_check_bus(type, busses)) { if (busses & IEC_BUS_IEC) { type = DRIVE_TYPE_1541; } else if (busses & IEC_BUS_IEEE) { type = DRIVE_TYPE_2031; } else { type = DRIVE_TYPE_NONE; } } if (is_drive0(dnr)) { if (drive_check_dual(type)) { int drive1 = mk_drive1(dnr); /* dual disk drives disable second emulated unit */ log_warning(drive->log, "Dual disk drive %d disables emulated drive %d", dnr, drive1); drive_resources_type(DRIVE_TYPE_NONE, int_to_void_ptr(drive1)); } } else { drive0 = drive_context[mk_drive0(dnr)]->drive; if (drive0->enable && drive_check_dual(drive0->type)) { /* dual disk drives disable second emulated unit */ log_warning(drive->log, "Dual disk drive %d disables emulated drive %d", mk_drive0(dnr), dnr); type = DRIVE_TYPE_NONE; } } if (type == DRIVE_TYPE_2000 || type == DRIVE_TYPE_4000) { if (drive->type != DRIVE_TYPE_2000 && drive->type != DRIVE_TYPE_4000) { rtc_device = lib_msprintf("FD%d", dnr + 8); drive->ds1216 = ds1216e_init(rtc_device); drive->ds1216->hours12 = 1; lib_free(rtc_device); } } else { if (drive->type == DRIVE_TYPE_2000 || drive->type == DRIVE_TYPE_4000) { if (drive->ds1216) { ds1216e_destroy(drive->ds1216, drive->rtc_save); drive->ds1216 = NULL; } } } switch (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: if (drive->type != type) { drive->current_half_track = 2 * 18; if ((type == DRIVE_TYPE_1001) || (type == DRIVE_TYPE_8050) || (type == DRIVE_TYPE_8250)) { drive->current_half_track = 2 * 38; } } drive->type = type; if (drive_true_emulation) { drive->enable = 1; drive_enable(drive_context[dnr]); /* 1551 drive does not use the IEC bus */ machine_bus_status_drivetype_set(dnr + 8, drive_check_bus(type, IEC_BUS_IEC)); } else { drive_enable_update_ui(drive_context[dnr]); } drive_set_disk_drive_type(type, drive_context[dnr]); driverom_initialize_traps(drive); machine_drive_idling_method(dnr); return 0; case DRIVE_TYPE_NONE: drive->type = type; drive_disable(drive_context[dnr]); machine_bus_status_drivetype_set(dnr + 8, 0); return 0; default: return -1; } }