Exemple #1
0
void datasette_set_motor(int flag)
{
    DBG(("datasette_set_motor(%d) (image present:%s)", flag, current_image ? "yes" : "no"));

    if (datasette_alarm == NULL) {
        DBG(("datasette_set_motor (datasette_alarm == NULL)"));
        return;
    }

    if (flag) {
        /* abort pending motor stop */
        motor_stop_clk = 0;
        if (!datasette_motor) {
            last_write_clk = (CLOCK)0;
            datasette_start_motor();
            ui_display_tape_motor_status(1);
            datasette_motor = 1;
        }
    }
    if (!flag && datasette_motor && motor_stop_clk == 0) {
        motor_stop_clk = maincpu_clk + MOTOR_DELAY;
        DBG(("datasette_set_motor(maincpu_clk:%d motor_stop_clk:%d)", maincpu_clk, motor_stop_clk));
        if (!datasette_alarm_pending) {
            /* make sure that the motor will stop */
            alarm_set(datasette_alarm, motor_stop_clk);
            datasette_alarm_pending = 1;
        }
    }
}
Exemple #2
0
void datasette_set_motor(int flag)
{
    if (current_image != NULL) {
        if (flag) {
            /* abort pending motor stop */
            motor_stop_clk = 0;
            if (!datasette_motor) {
                last_write_clk = (CLOCK)0;
                datasette_start_motor();
                ui_display_tape_motor_status(1);
                datasette_motor = 1;
            }
        }
        if (!flag && datasette_motor && motor_stop_clk == 0) {
            motor_stop_clk = maincpu_clk + MOTOR_DELAY;
            if (!datasette_alarm_pending) {
                /* make sure that the motor will stop */
                alarm_set(datasette_alarm, motor_stop_clk);
                datasette_alarm_pending = 1;
            }
        }
    }
}
Exemple #3
0
static void datasette_read_bit(CLOCK offset, void *data)
{
    double speed_of_tape = DS_V_PLAY;
    int direction = 1;
    long gap;

    alarm_unset(datasette_alarm);
    datasette_alarm_pending = 0;

    if (current_image == NULL)
        return;

    /* check for delay of motor stop */
    if (motor_stop_clk > 0 && maincpu_clk >= motor_stop_clk) {
        motor_stop_clk = 0;
        ui_display_tape_motor_status(0);
        datasette_motor = 0;
    }

    if (!datasette_motor)
        return;

    switch (current_image->mode) {
      case DATASETTE_CONTROL_START:
        direction = 1;
        speed_of_tape = DS_V_PLAY;
        if (!datasette_long_gap_pending)
            datasette_trigger_flux_change(fullwave);
        break;
      case DATASETTE_CONTROL_FORWARD:
        direction = 1;
        speed_of_tape = DS_RPS_FAST / DS_G
            * sqrt(4 * PI * DS_D
            * DS_V_PLAY / datasette_cycles_per_second * 8
            * current_image->cycle_counter
            + 4 * PI * PI * DS_R * DS_R);
        break;
      case DATASETTE_CONTROL_REWIND:
        direction = -1;
        speed_of_tape = DS_RPS_FAST / DS_G
            * sqrt(4 * PI * DS_D
            * DS_V_PLAY / datasette_cycles_per_second * 8
            * (current_image->cycle_counter_total
            - current_image->cycle_counter)
            + 4 * PI * PI * DS_R * DS_R);
        break;
      case DATASETTE_CONTROL_RECORD:
      case DATASETTE_CONTROL_STOP:
        return;
      default:
        log_error(datasette_log, "Unknown datasette mode.");
        return;
    }

    if (direction + datasette_last_direction == 0) {
        /* the direction changed; read the gap from file,
        but use use only the elapsed gap */
        gap = datasette_read_gap(direction);
        datasette_long_gap_pending = datasette_long_gap_elapsed;
        datasette_long_gap_elapsed = gap - datasette_long_gap_elapsed;
    }
    if (datasette_long_gap_pending) {
        gap = datasette_long_gap_pending;
        datasette_long_gap_pending = 0;
    } else {
        gap = datasette_read_gap(direction);
        if (gap)
            datasette_long_gap_elapsed = 0;
    }
    if (!gap) {
        datasette_control(DATASETTE_CONTROL_STOP);
        return;
    }
    if (gap > DATASETTE_MAX_GAP) {
        datasette_long_gap_pending = gap - DATASETTE_MAX_GAP;
        gap = DATASETTE_MAX_GAP;
    }
    datasette_long_gap_elapsed += gap;
    datasette_last_direction = direction;

    if (direction > 0)
        current_image->cycle_counter += gap / 8;
    else
        current_image->cycle_counter -= gap / 8;

    gap -= offset;

    if (gap > 0) {
        alarm_set(datasette_alarm, maincpu_clk +
                  (CLOCK)(gap * (DS_V_PLAY / speed_of_tape)));
        datasette_alarm_pending = 1;
    } else {
        /* If the offset is geater than the gap to the next flux
           change, the change happend during DMA.  Schedule it now.  */
        alarm_set(datasette_alarm, maincpu_clk);
        datasette_alarm_pending = 1;
    }
    datasette_update_ui_counter();
}