Exemplo n.º 1
0
static TUI_MENU_CALLBACK(datasette_callback)
{
    if (been_activated) {
        datasette_control((int)param);
    }
    return NULL;
}
Exemplo n.º 2
0
static void datasette_internal_reset(void)
{
    int mode = current_image ? current_image->mode : notape_mode;

    DBG(("datasette_internal_reset (mode:%d)", mode));

    if (mode == DATASETTE_CONTROL_START ||
        mode == DATASETTE_CONTROL_FORWARD ||
        mode == DATASETTE_CONTROL_REWIND) {
        alarm_unset(datasette_alarm);
        datasette_alarm_pending = 0;
    }
    datasette_control(DATASETTE_CONTROL_STOP);
    if (current_image != NULL) {
        if (!autostart_ignore_reset) {
            tap_seek_start(current_image);
        }
        current_image->cycle_counter = 0;
    }
    datasette_counter_offset = 0;
    datasette_long_gap_pending = 0;
    datasette_long_gap_elapsed = 0;
    datasette_last_direction = 0;
    motor_stop_clk = 0;
    datasette_update_ui_counter();
    fullwave = 0;
}
Exemplo n.º 3
0
inline static void bit_write(void)
{
    CLOCK write_time;
    BYTE write_gap;

    write_time = maincpu_clk - last_write_clk;
    last_write_clk = maincpu_clk;

    /* C16 TAPs use half the machine clock as base cycle */
    if (machine_class == VICE_MACHINE_PLUS4) {
        write_time = write_time / 2;
    }

    if (write_time < (CLOCK)7) {
        return;
    }

    if (write_time < (CLOCK)(255 * 8 + 7)) {
        write_gap = (BYTE)(write_time / (CLOCK)8);
        if (fwrite(&write_gap, 1, 1, current_image->fd) < 1) {
            datasette_control(DATASETTE_CONTROL_STOP);
            return;
        }
        current_image->current_file_seek_position++;
    } else {
        write_gap = 0;
        if (fwrite(&write_gap, 1, 1, current_image->fd) != 1) {
            log_debug("datasette bit_write failed.");
        }
        current_image->current_file_seek_position++;
        if (current_image->version >= 1) {
            BYTE long_gap[3];
            int bytes_written;
            long_gap[0] = (BYTE)(write_time & 0xff);
            long_gap[1] = (BYTE)((write_time >> 8) & 0xff);
            long_gap[2] = (BYTE)((write_time >> 16) & 0xff);
            write_time &= 0xffffff;
            bytes_written = (int)fwrite(long_gap, 1, 3, current_image->fd);
            current_image->current_file_seek_position += bytes_written;
            if (bytes_written < 3) {
                datasette_control(DATASETTE_CONTROL_STOP);
                return;
            }
        }
    }
Exemplo n.º 4
0
void uidatasette_command(HWND hwnd, WPARAM wparam)
{
    switch (wparam) {
    case IDM_DATASETTE_SETTINGS:
        uidatasette_settings_dialog(hwnd);
        break;
    case IDM_DATASETTE_CONTROL_STOP:
        datasette_control(DATASETTE_CONTROL_STOP);
        break;
    case IDM_DATASETTE_CONTROL_START:
        datasette_control(DATASETTE_CONTROL_START);
        break;
    case IDM_DATASETTE_CONTROL_FORWARD:
        datasette_control(DATASETTE_CONTROL_FORWARD);
        break;
    case IDM_DATASETTE_CONTROL_REWIND:
        datasette_control(DATASETTE_CONTROL_REWIND);
        break;
    case IDM_DATASETTE_CONTROL_RECORD:
        datasette_control(DATASETTE_CONTROL_RECORD);
        break;
    case IDM_DATASETTE_CONTROL_RESET:
        datasette_control(DATASETTE_CONTROL_RESET);
        break;
    case IDM_DATASETTE_RESET_COUNTER:
        datasette_control(DATASETTE_CONTROL_RESET_COUNTER);
        break;
    }
}
Exemplo n.º 5
0
void ui_datasette_tape_action_cb(GtkWidget *widget, gpointer data)
{
    int val = GPOINTER_TO_INT(data);
    if (val >= DATASETTE_CONTROL_STOP && val <= DATASETTE_CONTROL_RESET_COUNTER) {
        datasette_control(val);
    } else {
        fprintf(stderr, "Got an impossible Datasette Control action, code %ld (valid range %d-%d)\n", (long)val, DATASETTE_CONTROL_STOP, DATASETTE_CONTROL_RESET_COUNTER);
    }
}
Exemplo n.º 6
0
static void advance_pressplayontape(void)
{
    switch (check("PRESS PLAY ON TAPE", AUTOSTART_NOWAIT_BLINK)) {
      case YES:
        autostartmode = AUTOSTART_LOADINGTAPE;
        datasette_control(DATASETTE_CONTROL_START);
        break;
      case NO:
        autostart_disable();
        break;
      case NOT_YET:
        break;
    }
}
Exemplo n.º 7
0
inline static void bit_write(void)
{
    CLOCK write_time;
    BYTE write_gap;

    write_time = maincpu_clk - last_write_clk;
    last_write_clk = maincpu_clk;

    if (write_time < (CLOCK)7)
        return;

    if (write_time < (CLOCK)(255 * 8 + 7)) {
        write_gap = (BYTE)(write_time / (CLOCK)8);
        if (fwrite(&write_gap, 1, 1, current_image->fd) < 1) {
            datasette_control(DATASETTE_CONTROL_STOP);
            return;
        }
        current_image->current_file_seek_position++;
    } else {
        write_gap = 0;
        fwrite(&write_gap, 1, 1, current_image->fd);
        current_image->current_file_seek_position++;
        if (current_image->version >= 1) {
            BYTE long_gap[3];
            int bytes_written;
            long_gap[0] = (BYTE)(write_time & 0xff);
            long_gap[1] = (BYTE)((write_time >> 8) & 0xff);
            long_gap[2] = (BYTE)((write_time >> 16) & 0xff);
            write_time &= 0xffffff;
            bytes_written = fwrite(long_gap, 1, 3, current_image->fd);
            current_image->current_file_seek_position += bytes_written;
            if (bytes_written < 3) {
                datasette_control(DATASETTE_CONTROL_STOP);
                return;
            }
        }
    }
Exemplo n.º 8
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();
}
Exemplo n.º 9
0
static MRESULT EXPENTRY pm_datasette(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
    switch (msg)
    {
    case WM_INITDLG:
        {
            int val;

            WinSendMsg(hwnd, WM_COUNTER,  (void*)ui_status.lastTapeCounter, 0);
            WinSendMsg(hwnd, WM_TAPESTAT,
                       (void*)ui_status.lastTapeCtrlStat,
                       (void*)ui_status.lastTapeStatus);
            WinShowDlg(hwnd, SS_SPIN,
                       ui_status.lastTapeMotor && ui_status.lastTapeStatus);

            resources_get_int("DatasetteResetWithCPU", &val);
            WinCheckButton(hwnd, CB_RESETWCPU, val);
            resources_get_int("DatasetteZeroGapDelay", &val);
            WinSetDlgSpinVal(hwnd, SPB_DELAY, (val/100));
            resources_get_int("DatasetteSpeedTuning", &val);
            WinSetDlgSpinVal(hwnd, SPB_GAP, val);
        }
        break;

    case WM_COUNTER:
        WinSetDlgSpinVal(hwnd, SPB_COUNT, (ULONG)mp1);
        return FALSE;

    case WM_TAPESTAT:
        WinEnableControl(hwnd, PB_RECORD,   mp2 && (int)mp1!=DATASETTE_CONTROL_RECORD);
        WinEnableControl(hwnd, PB_REWIND,   mp2 && (int)mp1!=DATASETTE_CONTROL_REWIND);
        WinEnableControl(hwnd, PB_STOP,     mp2 && (int)mp1!=DATASETTE_CONTROL_STOP);
        WinEnableControl(hwnd, PB_START,    mp2 && (int)mp1!=DATASETTE_CONTROL_START);
        WinEnableControl(hwnd, PB_FORWARD,  mp2 && (int)mp1!=DATASETTE_CONTROL_FORWARD);
        WinEnableControl(hwnd, PB_RESET,    mp2!=0);
        WinEnableControl(hwnd, PB_RESETCNT, mp2!=0);
        WinEnableControl(hwnd, SPB_COUNT,   mp2!=0);

        if (!mp2)
            WinShowDlg(hwnd, SS_SPIN, 0);

        return FALSE;

    case WM_SPINNING:
        WinShowDlg(hwnd, SS_SPIN, mp1 && mp2);
        return FALSE;
 
    case WM_COMMAND:
        switch (LONGFROMMP(mp1))
        {
        case PB_STOP:
        case PB_START:
        case PB_FORWARD:
        case PB_REWIND:
        case PB_RECORD:
        case PB_RESET:
        case PB_RESETCNT:
            datasette_control(LONGFROMMP(mp1)&0xf);
            return FALSE;

        case PB_TATTACH:
            ViceFileDialog(hwnd, 0x0201, FDS_OPEN_DIALOG);
            return FALSE;

        case PB_TDETACH:
            tape_image_detach(1);
            return FALSE;
        }
        break;
    case WM_CONTROL:
        switch (SHORT1FROMMP(mp1))
        {
        case CB_RESETWCPU:
            toggle("DatasetteResetWithCPU");
            break;
        case SPB_DELAY:
            if (SHORT2FROMMP(mp1)==SPBN_ENDSPIN)
            {
                const ULONG val = WinGetSpinVal((HWND)mp2);
                resources_set_int("DatasetteZeroGapDelay", val*100);
            }
            break;
        case SPB_GAP:
            if (SHORT2FROMMP(mp1)==SPBN_ENDSPIN)
            {
                const ULONG val = WinGetSpinVal((HWND)mp2);
                resources_set_int("DatasetteSpeedTuning", val);
            }
            break;
        }
        break;
    }
    return WinDefDlgProc (hwnd, msg, mp1, mp2);
}
Exemplo n.º 10
0
/* Dispatch all the pending keyboard commands.  */
void kbd_flush_commands(void)
{
    int i;

    if (num_queued_commands == 0) {
        return;
    }

    for (i = 0; i < num_queued_commands; i++) {
        switch (command_queue[i].type) {
            case KCMD_HARD_RESET:
                vsync_suspend_speed_eval();
                machine_trigger_reset(MACHINE_RESET_MODE_HARD);
                break;
            case KCMD_RESET:
                vsync_suspend_speed_eval();
                machine_trigger_reset(MACHINE_RESET_MODE_SOFT);
                break;
            case KCMD_RESTORE_PRESSED:
                machine_set_restore_key(1);
                break;
            case KCMD_RESTORE_RELEASED:
                machine_set_restore_key(0);
                break;
            case KCMD_FREEZE:
                if (freeze_function != NULL) {
                    freeze_function();
                }
                break;
            case KCMD_FLIP_NEXT:
                fliplist_attach_head(8, 1);
                break;
            case KCMD_FLIP_PREVIOUS:
                fliplist_attach_head(8, 0);
                break;
            case KCMD_FLIP_ADD:
                fliplist_add_image(8);
                break;
            case KCMD_FLIP_REMOVE:
                fliplist_remove(-1, NULL);
                break;
            case KCMD_TOGGLE_WARP:
                resources_toggle("WarpMode", NULL);
                break;
            case KCMD_MENU:
                interrupt_maincpu_trigger_trap(menu_trap, (void *)command_queue[i].data);
                break;
            case KCMD_TOGGLE_STATUSBAR:
                if (statusbar_enabled()) {
                    resources_set_int("ShowStatusbar", STATUSBAR_MODE_OFF);
                } else {
                    resources_set_int("ShowStatusbar", STATUSBAR_MODE_ON);
                }
                break;
            case KCMD_DATASETTE_START:
                datasette_control(DATASETTE_CONTROL_START);
                break;
            case KCMD_DATASETTE_STOP:
                datasette_control(DATASETTE_CONTROL_STOP);
                break;
            case KCMD_DATASETTE_FORWARD:
                datasette_control(DATASETTE_CONTROL_FORWARD);
                break;
            case KCMD_DATASETTE_REWIND:
                datasette_control(DATASETTE_CONTROL_REWIND);
                break;
            case KCMD_DATASETTE_RECORD:
                datasette_control(DATASETTE_CONTROL_RECORD);
                break;
            default:
                log_error(LOG_DEFAULT, "Unknown keyboard command %d.", (int)command_queue[i].type);
        }
    }
    num_queued_commands = 0;
}
Exemplo n.º 11
0
static UI_CALLBACK(ui_datasette_control)
{
    int command = vice_ptr_to_int(UI_MENU_CB_PARAM);

    datasette_control(command);
}