Example #1
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;

    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;
}
Example #2
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;
    }
}