Exemplo n.º 1
0
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);
    }
}
Exemplo n.º 2
0
/* 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);
}
Exemplo n.º 3
0
/* 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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
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;

        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;
}
Exemplo n.º 8
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));
		}
	}
}
Exemplo n.º 9
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;
}