static void dtlbasic_write(int write_bit)
{
    if (write_bit == write_status) {
        return;
    }

    write_status = write_bit;

    if (dtlbasic_state == DTLBASIC_DONGLE_SENSE_LOW && write_bit) {
        dtlbasic_state = DTLBASIC_DONGLE_WRITE_HIGH;
        return;
    }

    if (dtlbasic_state == DTLBASIC_DONGLE_WRITE_HIGH && !write_bit) {
        dtlbasic_state = DTLBASIC_DONGLE_ACTIVE;
        dtlbasic_counter = 1;
        return;
    }

    if (!write_bit) {
        if (dtlbasic_counter != -1) {
            if (dtlbasic_key[dtlbasic_counter]) {
                tapeport_trigger_flux_change(1, dtlbasic_dongle_device.id);
            }
            ++dtlbasic_counter;
            if (dtlbasic_counter == 20) {
                dtlbasic_counter = -1;
            }
        }
    }
}
Esempio n. 2
0
void tapelog_trigger_flux_change_passthrough(unsigned int on)
{
    tapeport_trigger_flux_change(on, tapelog_device.id);

    tapelog_transition("read", (BYTE)on);

    tapelog_read_in = on;
}
Esempio n. 3
0
/* this is the alarm function */
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;

    DBG(("datasette_read_bit(motor:%d) %d>=%d (image present:%s)", datasette_motor, maincpu_clk, motor_stop_clk, current_image ? "yes" : "no"));

    /* 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;
    }
    DBG(("datasette_read_bit(motor:%d)", datasette_motor));

    if (!datasette_motor) {
        return;
    }

    if (current_image == NULL) {
        switch (notape_mode) {
            case DATASETTE_CONTROL_START:
            case DATASETTE_CONTROL_FORWARD:
            case DATASETTE_CONTROL_REWIND:
            case DATASETTE_CONTROL_RECORD:
                break;
            case DATASETTE_CONTROL_STOP:
                if (motor_stop_clk > 0) {
                    alarm_set(datasette_alarm, motor_stop_clk);
                    datasette_alarm_pending = 1;
                }
                break;
        }
        datasette_update_ui_counter();
        return;
    }

    switch (current_image->mode) {
        case DATASETTE_CONTROL_START:
            direction = 1;
            speed_of_tape = DS_V_PLAY;
            if (!datasette_long_gap_pending) {
                if (datasette_list_item) {
                    tapeport_trigger_flux_change(fullwave, datasette_device.id);
                }
            }
            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();
}