static void instrument_editor_load_instrument (gchar *fn) { STInstrument *instr = current_instrument; FILE *f; g_assert(instr != NULL); // Instead of locking the instrument and samples, we simply stop playing. gui_play_stop(); f = fopen(fn, "rb"); if(f) { statusbar_update(STATUS_LOADING_INSTRUMENT, TRUE); xm_load_xi(instr, f); statusbar_update(STATUS_INSTRUMENT_LOADED, FALSE); fclose(f); } else { error_error(_("Can't open file.")); } current_instrument = NULL; instrument_editor_set_instrument(instr); sample_editor_set_sample(&instr->samples[0]); }
static int wd_fdc_spinup( wd_fdc *f, libspectrum_byte b ) { libspectrum_dword delay = 0; if( f->state != WD_FDC_STATE_SEEK && ( b & 0x04 ) ) delay = 30; if( f->type == WD1770 || f->type == WD1772 ) { if( !( b & 0x08 ) && !( f->status_register & WD_FDC_SR_MOTORON ) ) { f->status_register |= WD_FDC_SR_MOTORON; fdd_motoron( &f->current_drive->fdd, 1 ); statusbar_update( 1 ); delay += 6 * 200; } } else { /* WD1773/FD1793 */ event_remove_type( motor_off_event ); if( f->state == WD_FDC_STATE_SEEK ) { if( b & 0x08 ) { f->head_load = 1; if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( &f->current_drive->fdd, 1 ); else fdd_head_load( &f->current_drive->fdd, 1 ); statusbar_update( 1 ); } else { f->head_load = 0; if( f->hlt_time > 0 ) f->hlt = 0; /* reset the trigger */ if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( &f->current_drive->fdd, 0 ); else fdd_head_load( &f->current_drive->fdd, 0 ); statusbar_update( 0 ); } return 0; } else { f->head_load = 1; if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( &f->current_drive->fdd, 1 ); else fdd_head_load( &f->current_drive->fdd, 1 ); statusbar_update( 1 ); if( f->hlt_time > 0 ) delay += f->hlt_time; } } if( delay ) { event_remove_type( fdc_event ); event_add_with_data( tstates + delay * machine_current->timings.processor_speed / 1000, fdc_event, f ); return 1; } return 0; }
static void update_info_visibility (GpaCardManager *cardman) { if (cardman->cardtype != G_TYPE_NONE) { char *tmp = g_strdup_printf (_("%s card detected."), cardman->cardtypename); statusbar_update (cardman, tmp); xfree (tmp); } else { statusbar_update (cardman, _("Checking for card...")); } }
static void instrument_editor_save_instrument (gchar *fn) { STInstrument *instr = current_instrument; FILE *f; g_assert(instr != NULL); f = fopen(fn, "wb"); if(f) { statusbar_update(STATUS_SAVING_INSTRUMENT, TRUE); xm_save_xi(instr, f); statusbar_update(STATUS_INSTRUMENT_SAVED, FALSE); fclose(f); } else { error_error(_("Can't open file.")); } }
static int wd_fdc_spinup( wd_fdc *f, libspectrum_byte b ) { libspectrum_dword delay = 0; fdd_t *d = f->current_drive; if( f->state != WD_FDC_STATE_SEEK && ( b & 0x04 ) ) delay = 30; if( f->type == WD1770 || f->type == WD1772 ) { if( !( f->status_register & WD_FDC_SR_MOTORON ) ) { f->status_register |= WD_FDC_SR_MOTORON; fdd_motoron( d, 1 ); statusbar_update( 1 ); if( !( b & 0x08 ) ) delay += 6 * 200; } } else { /* WD1773/FD1793/WD2797 */ event_remove_type( motor_off_event ); if( f->state == WD_FDC_STATE_SEEK ) { if( b & 0x08 ) { f->head_load = 1; if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( d, 1 ); else fdd_head_load( d, 1 ); statusbar_update( 1 ); } else if( !( b & 0x04 ) ) { /* HLD reset only if V flag == 0 too */ f->head_load = 0; if( !( f->flags & WD_FLAG_NOHLT ) && f->hlt_time > 0 ) f->hlt = 0; /* reset the trigger */ if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( d, 0 ); else fdd_head_load( d, 0 ); statusbar_update( 0 ); } return 0; } else { f->head_load = 1; if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( d, 1 ); else fdd_head_load( d, 1 ); statusbar_update( 1 ); if( f->hlt_time > 0 ) delay += f->hlt_time; } } /* For Type III commands on WD2797 */ if( f->type == WD2797 && ( b & 0xc0 ) == 0xc0 && ( b & 0x30 ) != 0x10 ) fdd_set_head( d, b & 0x02 ? 1 : 0 ); if( delay ) { event_remove_type( fdc_event ); event_add_with_data( tstates + delay * machine_current->timings.processor_speed / 1000, fdc_event, f ); return 1; } return 0; }
static void wd_fdc_event( libspectrum_dword last_tstates GCC_UNUSED, int event, void *user_data ) { wd_fdc *f = user_data; fdd_t *d = f->current_drive; if( event == timeout_event ) { if( f->state == WD_FDC_STATE_READ || f->state == WD_FDC_STATE_WRITE || f->state == WD_FDC_STATE_READTRACK || f->state == WD_FDC_STATE_WRITETRACK || f->state == WD_FDC_STATE_READID ) { f->state = WD_FDC_STATE_NONE; f->status_register |= WD_FDC_SR_LOST; f->status_register &= ~WD_FDC_SR_BUSY; wd_fdc_reset_datarq( f ); wd_fdc_set_intrq( f ); } return; } if( event == motor_off_event ) { if( f->type == WD1770 || f->type == WD1772 ) { f->status_register &= ~WD_FDC_SR_MOTORON; fdd_motoron( d, 0 ); } else { /* WD1773/FD1973 */ f->head_load = 0; if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( d, 0 ); else fdd_head_load( d, 0 ); } statusbar_update( 0 ); return; } if( ( f->type == WD1773 || f->type == FD1793 || f->type == WD2797 ) && f->hlt_time > 0 && f->head_load && !f->hlt ) f->hlt = 1; if( ( ( f->type == WD1770 || f->type == WD1772 ) && ( f->status_register & WD_FDC_SR_MOTORON ) && f->status_type == WD_FDC_STATUS_TYPE1 ) || ( ( f->type == WD1773 || f->type == FD1793 || f->type == WD2797 ) && ( f->state == WD_FDC_STATE_SEEK || f->state == WD_FDC_STATE_SEEK_DELAY ) && f->head_load ) ) { f->status_register |= WD_FDC_SR_SPINUP; } if( f->read_id ) { if( f->state == WD_FDC_STATE_VERIFY ) wd_fdc_seek_verify_read_id( f ); else if( ( f->state == WD_FDC_STATE_READ || f->state == WD_FDC_STATE_WRITE ) && f->datarq ) f->datarq = 0, wd_fdc_set_datarq( f ); else if( f->state == WD_FDC_STATE_READ || f->state == WD_FDC_STATE_WRITE ) wd_fdc_type_ii_seek( f ); else if( f->state == WD_FDC_STATE_READID ) wd_fdc_type_iii( f ); } else if( f->state == WD_FDC_STATE_SEEK || f->state == WD_FDC_STATE_SEEK_DELAY ) wd_fdc_type_i( f ); else if( f->state == WD_FDC_STATE_VERIFY ) wd_fdc_seek_verify( f ); else if( ( f->state == WD_FDC_STATE_READ || f->state == WD_FDC_STATE_WRITE ) && f->datarq ) f->datarq = 0, wd_fdc_set_datarq( f ); else if( f->state == WD_FDC_STATE_READ || f->state == WD_FDC_STATE_WRITE ) wd_fdc_type_ii( f ); else if( ( f->state == WD_FDC_STATE_READTRACK || f->state == WD_FDC_STATE_READID || f->state == WD_FDC_STATE_WRITETRACK ) && f->datarq ) f->datarq = 0, wd_fdc_set_datarq( f ); else if( f->state == WD_FDC_STATE_READTRACK || f->state == WD_FDC_STATE_READID || f->state == WD_FDC_STATE_WRITETRACK ) wd_fdc_type_iii( f ); }
static void wd_fdc_type_i( wd_fdc *f ) { libspectrum_byte b = f->command_register; fdd_t *d = f->current_drive; if( f->state == WD_FDC_STATE_SEEK_DELAY ) { /* after delay */ if( ( b & 0x60 ) != 0x00 ) /* STEP/STEP-IN/STEP-OUT */ goto type_i_verify; goto type_i_loop; } else { /* WD_FDC_STATE_SEEK */ f->status_register |= WD_FDC_SR_SPINUP; } if( ( b & 0x60 ) != 0x00 ) { /* STEP/STEP-IN/STEP-OUT */ if( b & 0x40 ) f->direction = b & 0x20 ? FDD_STEP_OUT : FDD_STEP_IN; if( b & 0x10 ) /* update? */ goto type_i_update; goto type_i_noupdate; } /* SEEK or RESTORE */ if ( !( b & 0x10 ) ) { /* RESTORE */ f->track_register = 0xff; f->data_register = 0; } type_i_loop: if( f->track_register != f->data_register ) { f->direction = f->track_register < f->data_register ? FDD_STEP_IN : FDD_STEP_OUT; type_i_update: f->track_register += f->direction == FDD_STEP_IN ? 1 : -1; type_i_noupdate: if( d->tr00 && f->direction == FDD_STEP_OUT ) { f->track_register = 0; } else { fdd_step( d, f->direction ); f->state = WD_FDC_STATE_SEEK_DELAY; event_remove_type( fdc_event ); event_add_with_data( tstates + f->rates[ b & 0x03 ] * machine_current->timings.processor_speed / 1000, fdc_event, f ); return; } } type_i_verify: if( b & 0x04 ) { if( f->type == WD1773 || f->type == FD1793 || f->type == WD2797 ) { f->head_load = 1; event_remove_type( motor_off_event ); if( f->flags & WD_FLAG_BETA128 ) fdd_motoron( d, 1 ); else fdd_head_load( d, 1 ); event_remove_type( fdc_event ); event_add_with_data( tstates + 15 * /* 15ms */ machine_current->timings.processor_speed / 1000, fdc_event, f ); statusbar_update( 1 ); } f->state = WD_FDC_STATE_VERIFY; if( ( f->type == WD1770 || f->type == WD1772 ) && !( f->status_register & WD_FDC_SR_MOTORON ) ) { f->status_register |= WD_FDC_SR_MOTORON; fdd_motoron( f->current_drive, 1 ); statusbar_update( 1 ); event_remove_type( fdc_event ); event_add_with_data( tstates + 12 * /* 6 revolution 6 * 200 / 1000 */ machine_current->timings.processor_speed / 10, fdc_event, f ); return; } wd_fdc_seek_verify( f ); return; } if( d->tr00 ) f->status_register |= WD_FDC_SR_LOST; else f->status_register &= ~WD_FDC_SR_LOST; f->state = WD_FDC_STATE_NONE; f->status_register &= ~WD_FDC_SR_BUSY; wd_fdc_set_intrq( f ); }
/* This function is called to trigger a card-reload. */ static void card_reload (GpaCardManager *cardman) { gpg_error_t err, operr; const char *application; char *command_buf = NULL; const char *command; const char *err_desc = NULL; char *err_desc_buffer = NULL; int auto_app; if (!cardman->gpgagent) return; /* No support for GPGME_PROTOCOL_ASSUAN. */ /* Start the ticker if not yet done. */ start_ticker (cardman); if (!cardman->in_card_reload) { cardman->in_card_reload++; update_info_visibility (cardman); cardman->cardtype = G_TYPE_NONE; cardman->cardtypename = "Unknown"; /* The first thing we need to do is to issue the SERIALNO command; this makes sure that scdaemon initalizes the card if that has not yet been done. */ command = "SCD SERIALNO"; if (cardman->app_selector && (gtk_combo_box_get_active (GTK_COMBO_BOX (cardman->app_selector)) > 0) && (application = gtk_combo_box_get_active_text (GTK_COMBO_BOX (cardman->app_selector)))) { command_buf = g_strdup_printf ("%s %s", command, application); command = command_buf; auto_app = 0; } else auto_app = 1; err = gpgme_op_assuan_transact_ext (cardman->gpgagent, command, scd_data_cb, NULL, scd_inq_cb, NULL, scd_status_cb, cardman, &operr); if (!err) { err = operr; if (!auto_app && gpg_err_source (err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_CONFLICT) { /* Not in auto select mode and the scdaemon told us about a conflicting use. We now do a restart and try again to display an application selection conflict error only if it is not due to our own connection to the scdaemon. */ if (!gpgme_op_assuan_transact_ext (cardman->gpgagent, "SCD RESTART", NULL, NULL, NULL, NULL, NULL, NULL, &operr) && !operr) { err = gpgme_op_assuan_transact_ext (cardman->gpgagent, command, scd_data_cb, NULL, scd_inq_cb, NULL, scd_status_cb, cardman, &operr); if (!err) err = operr; } } } if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT || gpg_err_code (err) == GPG_ERR_CARD_REMOVED) { err_desc = _("No card found."); } else if (gpg_err_source (err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_CONFLICT) { err_desc = auto_app ? _("The selected card application is currently not available.") : _("Another process is using a different card application " "than the selected one.\n\n" "You may change the application selection mode to " "\"Auto\" to select the active application."); } else if (!auto_app && gpg_err_source (err) == GPG_ERR_SOURCE_SCD && gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED) { err_desc = _("The selected card application is not available."); } else if (err) { g_debug ("assuan command `%s' failed: %s <%s>\n", command, gpg_strerror (err), gpg_strsource (err)); if (!gpgme_op_assuan_transact_ext (cardman->gpgagent, "SCD SERIALNO undefined", NULL, NULL, NULL, NULL, NULL, NULL, &operr) && !operr) err = 0; else { err_desc = _("Error accessing the card."); statusbar_update (cardman, _("Error accessing card")); } } g_free (command_buf); if (!err) { /* Get the event counter to avoid a duplicate reload due to the ticker. */ gpgme_op_assuan_transact_ext (cardman->gpgagent, "GETEVENTCOUNTER", NULL, NULL, NULL, NULL, scd_status_cb, cardman, NULL); /* Now we need to get the APPTYPE of the card so that the correct GpaCM* object can can act on the data. */ command = "SCD GETATTR APPTYPE"; err = gpgme_op_assuan_transact_ext (cardman->gpgagent, command, scd_data_cb, NULL, scd_inq_cb, NULL, scd_status_cb, cardman, &operr); if (!err) err = operr; if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT || gpg_err_code (err) == GPG_ERR_CARD_REMOVED) statusbar_update (cardman, _("No card")); else if (err) { g_debug ("assuan command `%s' failed: %s <%s>\n", command, gpg_strerror (err), gpg_strsource (err)); statusbar_update (cardman, _("Error accessing card")); } } update_card_widget (cardman, err_desc); g_free (err_desc_buffer); err_desc_buffer = NULL; err_desc = NULL; update_title (cardman); update_info_visibility (cardman); /* We decrement our lock using a idle handler with lo priority. This gives us a better chance not to do a reload a second time on behalf of the file watcher or ticker. */ g_object_ref (cardman); g_idle_add_full (G_PRIORITY_LOW, card_reload_finish_idle_cb, cardman, NULL); } }