int drive_check_type(unsigned int drive_type, unsigned int dnr) { if (!drive_check_bus(drive_type, iec_available_busses())) return 0; if (drive_check_dual(drive_type)) { if (is_drive1(dnr)) { /* Dual drives only supported on even device numbers. */ return 0; } else { if (drive_context[mk_drive1(dnr)]->drive->type != DRIVE_TYPE_NONE) /* Disable dual drive if second device is enabled. */ return 0; } } else { if (is_drive1(dnr)) { if (drive_check_dual(drive_context[mk_drive0(dnr)]->drive->type)) /* Disable second device if dual drive is enabled. */ return drive_type == DRIVE_TYPE_NONE; } } if (machine_drive_rom_check_loaded(drive_type) < 0) return 0; return 1; }
/* Update the status bar in the UI. */ void drive_update_ui_status(void) { int i; if (console_mode || vsid_mode) return; /* Update the LEDs and the track indicators. */ for (i = 0; i < DRIVE_NUM; i++) { drive_t *drive; drive = drive_context[i]->drive; if (drive->enable || ((i == 1) && drive_context[0]->drive->enable && drive_check_dual(drive_context[0]->drive->type))) { drive_led_update(drive); if (drive->current_half_track != drive->old_half_track) { drive->old_half_track = drive->current_half_track; ui_display_drive_track(i, (i < 2 && drive_context[0]->drive->enable && drive_check_dual(drive_context[0]->drive->type)) ? 0 : 8, drive->current_half_track); } } } }
int drive_check_type(unsigned int drive_type, unsigned int dnr) { if (!drive_check_bus(drive_type, dnr, iec_available_busses())) return 0; if (drive_check_dual(drive_type)) { if (dnr > 0) { /* A second dual drive is not supported. */ return 0; } else { if (drive_context[1]->drive->type != DRIVE_TYPE_NONE) /* Disable dual drive if second drive is enabled. */ return 0; } } /* If the first drive is dual no second drive is supported at all. */ if (drive_check_dual(drive_context[0]->drive->type) && dnr > 0) return 0; if (machine_drive_rom_check_loaded(drive_type) < 0) return 0; return 1; }
/* Activate full drive emulation. */ int drive_enable(drive_context_t *drv) { int i, drive_true_emulation = 0; unsigned int dnr; drive_t *drive; unsigned int enabled_drives = 0; dnr = drv->mynumber; drive = drv->drive; /* This must come first, because this might be called before the drive initialization. */ if (!rom_loaded) return -1; resources_get_int("DriveTrueEmulation", &drive_true_emulation); /* Always disable kernal traps. */ if (!drive_true_emulation) return 0; if (drive->type == DRIVE_TYPE_NONE) return 0; /* Recalculate drive geometry. */ if (drive->image != NULL) drive_image_attach(drive->image, dnr + 8); drivecpu_wake_up(drv); /* Make sure the UI is updated. */ for (i = 0; i < DRIVE_NUM; i++) { unsigned int the_drive; the_drive = 1 << i; if (drive_context[i]->drive->enable) { enabled_drives |= the_drive; drive_context[i]->drive->old_led_status = -1; drive_context[i]->drive->old_half_track = -1; } } /* FIXME: this doesn't care about dual drives anymore */ drive_set_active_led_color(drive->type, dnr); ui_enable_drive_status(enabled_drives, drive_led_color); #if 0 /* this is the old code not respecting more than 2 drives */ ui_enable_drive_status((drive_context[0]->drive->enable ? UI_DRIVE_ENABLE_0 : 0) | ((drive_context[1]->drive->enable || (drive_context[0]->drive->enable && drive_check_dual(drive_context[0]->drive->type)) ) ? UI_DRIVE_ENABLE_1 : 0), drive_led_color); #endif return 0; }
int drive_num_leds(unsigned int dnr) { if (drive_check_old(drive_context[dnr]->drive->type)) return 2; if ((dnr == 1) && drive_check_dual(drive_context[0]->drive->type)) return 2; return 1; }
void fdc_reset(unsigned int fnum, unsigned int drive_type) { fdc_t *thefdc = &fdc[fnum]; int drive1 = mk_drive1(fnum); disk_image_t *saved_image0, *saved_image1; #ifdef FDC_DEBUG log_message(fdc_log, "fdc_reset: drive %d type=%d\n",fnum, drive_type); #endif saved_image0 = fdc[fnum].realimage; saved_image1 = NULL; /* detach disk images */ if (thefdc->image) { thefdc->wps_change = 0; fdc_detach_image(thefdc->image, fnum + 8); } if (thefdc->num_drives == 2) { saved_image1 = fdc[drive1].realimage; if (fdc[drive1].image) { fdc[drive1].wps_change = 0; fdc_detach_image(fdc[drive1].image, drive1 + 8); } } if (drive_check_old(drive_type)) { thefdc->drive_type = drive_type; thefdc->num_drives = is_drive1(fnum) ? 1 : drive_check_dual(drive_type) ? 2 : 1; thefdc->fdc_state = FDC_RESET0; alarm_set(thefdc->fdc_alarm, drive_clk[fnum] + 20); } else { thefdc->drive_type = DRIVE_TYPE_NONE; alarm_unset(thefdc->fdc_alarm); thefdc->fdc_state = FDC_UNUSED; thefdc->num_drives = 0; } /* re-attach disk images */ if (saved_image0) { #ifdef FDC_DEBUG printf("ieee/fdc.c:fdc_reset dev %d type %d drive 0 re-attach image %p (drive: %p)\n", fnum+8, drive_type, saved_image0, drive_context[fnum]->drive->image); #endif fdc_attach_image(saved_image0, fnum + 8); } if (saved_image1) { #ifdef FDC_DEBUG printf("ieee/fdc.c:fdc_reset dev %d type %d drive 1 re-attach image %p (drive: %p)\n", fnum+8, drive_type, saved_image0, drive_context[drive1]->drive->image); #endif fdc_attach_image(saved_image1, drive1 + 8); } }
/* Disable full drive emulation. */ void drive_disable(drive_context_t *drv) { int i, drive_true_emulation = 0; unsigned int dnr; drive_t *drive; unsigned int enabled_drives = 0; dnr = drv->mynumber; drive = drv->drive; /* This must come first, because this might be called before the true drive initialization. */ drive->enable = 0; resources_get_int("DriveTrueEmulation", &drive_true_emulation); if (rom_loaded) { drivecpu_sleep(drv); machine_drive_port_default(drv); drive_gcr_data_writeback(drive); } /* Make sure the UI is updated. */ for (i = 0; i < DRIVE_NUM; i++) { unsigned int the_drive; the_drive = 1 << i; if (drive_context[i]->drive->enable) { enabled_drives |= the_drive; drive_context[i]->drive->old_led_status = -1; drive_context[i]->drive->old_half_track = -1; } } ui_enable_drive_status(enabled_drives, drive_led_color); #if 0 ui_enable_drive_status((drive_context[0]->drive->enable ? UI_DRIVE_ENABLE_0 : 0) | ((drive_context[1]->drive->enable || (drive_context[0]->drive->enable && drive_check_dual(drive_context[0]->drive->type)) ) ? UI_DRIVE_ENABLE_1 : 0), drive_led_color); /* ui_enable_drive_status((drive_context[0]->drive->enable ? UI_DRIVE_ENABLE_0 : 0) | (drive_context[1]->drive->enable ? UI_DRIVE_ENABLE_1 : 0), drive_led_color); */ #endif }
int drive_set_disk_drive_type(unsigned int type, struct drive_context_s *drv) { unsigned int dnr; drive_t *drive; drive_t *drive1; dnr = drv->mynumber; if (machine_drive_rom_check_loaded(type) < 0) { return -1; } drive = drv->drive; rotation_rotate_disk(drive); drivesync_clock_frequency(type, drive); rotation_init(0, dnr); drive->type = type; if (type == DRIVE_TYPE_2000 || type == DRIVE_TYPE_4000) { drivecpu65c02_setup_context(drv, 0); } else { drivecpu_setup_context(drv, 0); } drive->side = 0; machine_drive_rom_setup_image(dnr); drivesync_factor(drv); drive_set_active_led_color(type, dnr); /* set up (relatively) easy detection of dual drives */ drive1 = drive_context[mk_drive1(dnr)]->drive; drive->drive0 = NULL; drive1->drive1 = NULL; if (is_drive0(dnr) && drive_check_dual(type)) { drive->drive1 = drive1; drive1->drive0 = drive; } else { drive->drive1 = NULL; drive1->drive0 = NULL; } if (type == DRIVE_TYPE_2000 || type == DRIVE_TYPE_4000) { drivecpu65c02_init(drv, type); } else { drivecpu_init(drv, type); } return 0; }
static void store_prb(riot_context_t *riot_context, BYTE byte) { driveriot2_context_t *riot2p; riot2p = (driveriot2_context_t *)(riot_context->prv); /* bit 3 Act LED 1 */ /* bit 4 Act LED 0 */ /* bit 5 Error LED */ /* 1001 only needs LED 0 and Error LED */ riot2p->drive->led_status = (byte >> 4) & 0x03; if ((is_drive0(riot2p->number)) && (drive_check_dual(riot2p->drive->type))) { drive_context[mk_drive1(riot2p->number)]->drive->led_status = ((byte & 8) ? 1 : 0) | ((byte & 32) ? 2 : 0); } }
static void undump_prb(riot_context_t *riot_context, BYTE byte) { driveriot2_context_t *riot2p; riot2p = (driveriot2_context_t *)(riot_context->prv); /* bit 3 Act LED 1 */ /* bit 4 Act LED 0 */ /* bit 5 Error LED */ /* 1001 only needs LED 0 and Error LED */ riot2p->drive->led_status = (byte >> 4) & 0x03; if ((is_drive0(riot2p->number)) && (drive_check_dual(riot2p->drive->type))) { drive_context[mk_drive1(riot2p->number)]->drive->led_status = ((byte & 8) ? 1 : 0) | ((byte & 32) ? 2 : 0); } if (riot2p->drive->led_status & 1) { riot2p->drive->led_active_ticks += *(riot_context->clk_ptr) - riot2p->drive->led_last_change_clk; } riot2p->drive->led_last_change_clk = *(riot_context->clk_ptr); }
static int drive_resources_type(int val, void *param) { unsigned int type, dnr; int busses; drive_t *drive, *drive0; 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; } } switch (type) { 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; } }
static int drive0_resources_type(int val, void *param) { unsigned int type; int busses; drive_t *drive; drive = drive_context[0]->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, 0, 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 (drive_check_dual(type)) { /* dual disk drives disable second emulated unit */ #ifdef CELL_DEBUG printf("WARNING: Dual disk drive disables second emulated drive\n"); #endif drive1_resources_type(DRIVE_TYPE_NONE, NULL); } switch (type) { 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_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[0]); /* 1551 drive does not use the IEC bus */ machine_bus_status_drivetype_set(8, drive_check_bus(type, 0, IEC_BUS_IEC)); } drive_set_disk_drive_type(type, drive_context[0]); driverom_initialize_traps(drive); machine_drive_idling_method(0); return 0; case DRIVE_TYPE_NONE: drive->type = type; drive_disable(drive_context[0]); machine_bus_status_drivetype_set(8, 0); return 0; default: return -1; } }