Exemple #1
0
void fade(bool fade_in, bool updatewps)
{
    int fp_global_vol = global_settings.volume << 8;
    int fp_min_vol = sound_min(SOUND_VOLUME) << 8;
    int fp_step = (fp_global_vol - fp_min_vol) / 10;

    skin_get_global_state()->is_fading = !fade_in;
    if (fade_in) {
        /* fade in */
        int fp_volume = fp_min_vol;

        /* zero out the sound */
        sound_set_volume(fp_min_vol >> 8);

        sleep(HZ/10); /* let audio thread run */
        audio_resume();
        
        if (updatewps)
            update_non_static();

        while (fp_volume < fp_global_vol - fp_step) {
            fp_volume += fp_step;
            sound_set_volume(fp_volume >> 8);
            sleep(1);
        }
        sound_set_volume(global_settings.volume);
    }
    else {
Exemple #2
0
int SndOpen()
{
unsigned int BufferSize;
unsigned int bufferStart;

	BufferSize = (nBurnSoundLen * nAudioChannels * AUDIO_BLOCKS)*2+512;
	EzxAudioBuffer= (unsigned short *)malloc(BufferSize);
	AudioBufferSize = nBurnSoundLen * nAudioChannels * 2;
	memset(EzxAudioBuffer,0,BufferSize);
	EzxAudioBuffer[1]=(EzxAudioBuffer[0]=(nBurnSoundLen * nAudioChannels * 2));
	EzxAudioBuffer[2]=(1000000000/nBurnSoundRate)&0xFFFF;
	EzxAudioBuffer[3]=(1000000000/nBurnSoundRate)>>16;
	bufferStart = (unsigned int)&EzxAudioBuffer[4];
	pOutput[0] = (short*)bufferStart;
	pOutput[1] = (short*)(bufferStart+1*EzxAudioBuffer[1]);
	pOutput[2] = (short*)(bufferStart+2*EzxAudioBuffer[1]);
	pOutput[3] = (short*)(bufferStart+3*EzxAudioBuffer[1]);
	pOutput[4] = (short*)(bufferStart+4*EzxAudioBuffer[1]);
	pOutput[5] = (short*)(bufferStart+5*EzxAudioBuffer[1]);
	pOutput[6] = (short*)(bufferStart+6*EzxAudioBuffer[1]);
	pOutput[7] = (short*)(bufferStart+7*EzxAudioBuffer[1]);
	if ( !GameMute )
	{
	int frag = 10 + config_options.option_samplerate;
    	frag |= 2 << 16;


		if (config_options.option_sound_enable==1)
		{
		    dspfd = ezx_open_dsp ( nBurnSoundRate, nAudioChannels, AUDIO_FORMAT, frag );
            if (dspfd >= 0)
            {
                pthread_create(&soundthread_p, NULL, &soundthread_f, NULL);
                return 0;
            }
		}
		if (config_options.option_sound_enable==2)
		{
            for(int i=0;i<NUM_BUFS;i++) buffer[i]=(unsigned char *) malloc(BUFFSIZE);
            SAMPLESIZE=512;  //lowest value accepted by audio driver
            dspfd=configure(nBurnSoundRate,nAudioChannels,AUDIO_S16);
		}
		// printf("SOUND: Init done (%d)\n", dspfd);
		if (((dspfd > 0)  && (config_options.option_sound_enable==2))  || ((dspfd>=0) && (config_options.option_sound_enable==1)))
		{
		    if (config_options.option_sound_enable==2) pBurnSoundOut  = (short*)pOutput[0];
		    if (config_options.option_sound_enable==2) audio_resume();


			return 0;
		}
		else
		{
			nBurnSoundRate	= 0;
			nBurnSoundLen	= 0;
		}
	}
	sampletime=EZX_GetTicks();
	return -1;
}
Exemple #3
0
void fade(bool fade_in, bool updatewps)
{
    int fp_global_vol = global_settings.volume << 8;
    int fp_min_vol = sound_min(SOUND_VOLUME) << 8;
    int fp_step = (fp_global_vol - fp_min_vol) / 30;
    int i;
    skin_get_global_state()->is_fading = !fade_in;
    if (fade_in) {
        /* fade in */
        int fp_volume = fp_min_vol;

        /* zero out the sound */
        sound_set_volume(fp_min_vol >> 8);

        sleep(HZ/10); /* let audio thread run */
        audio_resume();
        
        while (fp_volume < fp_global_vol - fp_step) {
            fp_volume += fp_step;
            sound_set_volume(fp_volume >> 8);
            if (updatewps)
            {
                FOR_NB_SCREENS(i)
                    skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
            }
            sleep(1);
        }
        sound_set_volume(global_settings.volume);
    }
    else {
Exemple #4
0
void play_click(int sound)
{
	int snd_bf_pointer;
	uae_s16 gui_volume;
	
	if (!changed_prefs.gui_volume) return;
	if (changed_prefs.sound_stereo!=1) return; //Only stereo implemented
	
	gui_volume = 5-changed_prefs.gui_volume;
	
	if (gui_volume<0) gui_volume=0;
	if (gui_volume>5) gui_volume=5;
	
	audio_resume();
	
	for(snd_bf_pointer=0; snd_bf_pointer< (len_click_buffer[sound]-sndbufsize); snd_bf_pointer+=sndbufsize)
	{
		memcpy_volume((uae_s16 *)sndbuffer, (uae_s16 *)(click_buffer_pointer[sound]+snd_bf_pointer), sndbufsize, gui_volume);
		finish_sound_buffer();
	}
	
	memcpy(sndbuffer, click_buffer_pointer[sound] + snd_bf_pointer, len_click_buffer[sound] - snd_bf_pointer); //The last chunk
	memset((char *) sndbuffer + len_click_buffer[sound]-snd_bf_pointer,0, sndbufsize -(len_click_buffer[sound]- snd_bf_pointer));
	finish_sound_buffer();
	clearbuffer();
	
	audio_pause();
}
Exemple #5
0
void unpause_action(bool may_fade, bool updatewps)
{
#if CONFIG_CODEC == SWCODEC
    /* Do audio first, then update, unless skin were to use its local
       status in which case, reverse it */
    audio_resume();

    if (updatewps)
        update_non_static();
#else
    if (may_fade && global_settings.fade_on_stop)
        fade(true, updatewps);
    else
        audio_resume();
#endif

    (void)may_fade;
}        
Exemple #6
0
void ab_jump_to_A_marker(void)
{
#if (CONFIG_CODEC != SWCODEC)
    bool paused = (audio_status() & AUDIO_STATUS_PAUSE) != 0;
    if ( ! paused )
        audio_pause();
#endif
    audio_ff_rewind(ab_A_marker);
#if (CONFIG_CODEC != SWCODEC)
    if ( ! paused )
        audio_resume();
#endif
}
Exemple #7
0
/* takes care of seeking to a track in a playlist
 * returns false if audio  isn't playing */
static bool seek(unsigned long pos)
{
    if (!(audio_status() & AUDIO_STATUS_PLAY))
    {
        return false;
    }
    else
    {
#if (CONFIG_CODEC == SWCODEC)
        audio_pre_ff_rewind();
        audio_ff_rewind(pos);
#else
        audio_pause();
        audio_ff_rewind(pos);
        audio_resume();
#endif
        return true;
    }
}
static int play(void* output_samples,int num_bytes,int flags)
{
    int wrote, b_digital;
    SInt32 exit_reason;

    // Check whether we need to reset the digital output stream.
    if (ao->b_digital && ao->b_stream_format_changed)
    {
        ao->b_stream_format_changed = 0;
        b_digital = AudioStreamSupportsDigital(ao->i_stream_id);
        if (b_digital)
        {
            /* Current stream supports digital format output, let's set it. */
            ao_msg(MSGT_AO, MSGL_V,
                   "Detected current stream supports digital, try to restore digital output...\n");

            if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format))
            {
                ao_msg(MSGT_AO, MSGL_WARN, "Restoring digital output failed.\n");
            }
            else
            {
                ao_msg(MSGT_AO, MSGL_WARN, "Restoring digital output succeeded.\n");
                reset();
            }
        }
        else
            ao_msg(MSGT_AO, MSGL_V, "Detected current stream does not support digital.\n");
    }

    wrote=write_buffer(output_samples, num_bytes);
    audio_resume();

    do {
        exit_reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, true);
    } while (exit_reason == kCFRunLoopRunHandledSource);

    return wrote;
}
Exemple #9
0
int 
psp_main_menu(void)
{
  gp2xCtrlData c;
  long        new_pad;
  long        old_pad;
  int         last_time;
  int         end_menu;

  audio_pause();

  cap32_save_back_to_blit();

  psp_kbd_wait_no_button();

  old_pad   = 0;
  last_time = 0;
  end_menu  = 0;

  while (! end_menu)
  {
    psp_display_screen_menu();
    psp_sdl_flip();

    while (1)
    {
      gp2xCtrlReadBufferPositive(&c, 1);
      c.Buttons &= PSP_ALL_BUTTON_MASK;

      if (c.Buttons) break;
    }

    new_pad = c.Buttons;

    if ((old_pad != new_pad) || ((c.TimeStamp - last_time) > PSP_MENU_MIN_TIME)) {
      last_time = c.TimeStamp;
      old_pad = new_pad;

    } else continue;

    if ((c.Buttons & GP2X_CTRL_LTRIGGER) == GP2X_CTRL_LTRIGGER) {
      psp_settings_menu();
      old_pad = new_pad = 0;
    } else
    if ((c.Buttons & GP2X_CTRL_RTRIGGER) == GP2X_CTRL_RTRIGGER) {
      psp_main_menu_reset();
      end_menu = 1;
    } else
    if ((new_pad == GP2X_CTRL_LEFT ) || 
        (new_pad == GP2X_CTRL_RIGHT) ||
        (new_pad == GP2X_CTRL_CROSS) || 
        (new_pad == GP2X_CTRL_CIRCLE))
    {
      int step = 0;

      if (new_pad & GP2X_CTRL_RIGHT) {
        step = 1;
      } else
      if (new_pad & GP2X_CTRL_LEFT) {
        step = -1;
      }

      switch (cur_menu_id ) 
      {
        case MENU_LOAD_SLOT : if (step) psp_main_menu_cur_slot(step);
                              else if (psp_main_menu_load_slot()) end_menu = 1;
        break;
        case MENU_SAVE_SLOT : if (step) psp_main_menu_cur_slot(step);
                              else      psp_main_menu_save_slot();
        break;
        case MENU_DEL_SLOT  : if (step) psp_main_menu_cur_slot(step);
                              else      psp_main_menu_del_slot();
        break;

        case MENU_LOAD_SNA  : if (psp_main_menu_load(FMGR_FORMAT_SNA, 0)) end_menu = 1;
                              old_pad = new_pad = 0;
        break;              
        case MENU_LOAD_DSKA : if (psp_main_menu_load(FMGR_FORMAT_DSK, 'A')) {
                                if (CPC.psp_explore_disk == CPC_EXPLORE_LOAD) {
                                  if (psp_disk_menu()) {
                                    end_menu = 1;
                                  }
                                } else 
                                if (CPC.psp_explore_disk >= CPC_EXPLORE_AUTO) {
                                  if (psp_disk_auto()) {
                                    end_menu = 1;
                                  }
                                }
                              }
                              old_pad = new_pad = 0;
        break;

        case MENU_LOAD_DSKB : psp_main_menu_load(FMGR_FORMAT_DSK, 'B');
                              old_pad = new_pad = 0;
        break;

        case MENU_COMMAND   : if (step) psp_main_menu_cur_command(step);
                              else { 
                                 psp_main_menu_command();
                                 end_menu = 1;
                              }
        break;

        case MENU_EDITOR    : psp_main_menu_editor();
                              old_pad = new_pad = 0;
        break;

        case MENU_CHEATS    : psp_cheat_menu();
                              old_pad = new_pad = 0;
        break;              

        case MENU_KEYBOARD   : psp_keyboard_menu();
                               old_pad = new_pad = 0;
        break;
        case MENU_JOYSTICK   : psp_joystick_menu();
                               old_pad = new_pad = 0;
        break;
        case MENU_SETTINGS   : psp_settings_menu();
                               old_pad = new_pad = 0;
        break;

        case MENU_SCREENSHOT : psp_main_menu_screenshot();
                               end_menu = 1;
        break;              

        case MENU_RESET     : psp_main_menu_reset();
                              end_menu = 1;
        break;

        case MENU_BACK      : end_menu = 1;
        break;

        case MENU_EXIT      : psp_main_menu_exit();
        break;

        case MENU_HELP      : psp_help_menu();
                              old_pad = new_pad = 0;
        break;              
      }

    } else
    if(new_pad & GP2X_CTRL_UP) {

      if (cur_menu_id > 0) cur_menu_id--;
      else                 cur_menu_id = MAX_MENU_ITEM-1;

    } else
    if(new_pad & GP2X_CTRL_DOWN) {

      if (cur_menu_id < (MAX_MENU_ITEM-1)) cur_menu_id++;
      else                                 cur_menu_id = 0;

    } else  
    if(new_pad & GP2X_CTRL_SQUARE) {
      /* Cancel */
      end_menu = -1;
    } else 
    if((new_pad & GP2X_CTRL_SELECT) == GP2X_CTRL_SELECT) {
      /* Back to CPC */
      end_menu = 1;
    }
  }
 
  psp_kbd_wait_no_button();

  psp_sdl_clear_screen( PSP_MENU_BLACK_COLOR );
  psp_sdl_flip();
  psp_sdl_clear_screen( PSP_MENU_BLACK_COLOR );
  psp_sdl_flip();

  psp_sdl_clear_blit(0);

  audio_resume();

  return 1;
}
Exemple #10
0
/*
 * Here's where all the action takes place!
 */
void real_main (int argc, char **argv)
{
    show_version ();

#if defined (NATMEM_OFFSET)
    if (NATMEM_OFFSET == 0 && sizeof (void*) < 8) {
      write_log ("NATMEM_OFFSET is 0; I hope you used 'uae-preloader' to load me, or else ...\n");
    }
#endif

#ifdef FILESYS
    currprefs.mountinfo = changed_prefs.mountinfo = &options_mountinfo;
#endif
    restart_program = 1;
#ifdef _WIN32
    sprintf (restart_config, "%sConfigurations\\", start_path);
#endif
    strcat (restart_config, OPTIONSFILENAME);

    /* Initial state is stopped */
    uae_target_state = UAE_STATE_STOPPED;

    while (uae_target_state != UAE_STATE_QUITTING) {
	int want_gui;

	set_state (uae_target_state);

	do_preinit_machine (argc, argv);

	/* Should we open the GUI? TODO: This mess needs to go away */
	want_gui = currprefs.start_gui;
	if (restart_program == 2)
	    want_gui = 0;
	else if (restart_program == 3)
	    want_gui = 1;

	changed_prefs = currprefs;


	if (want_gui) {
	    /* Handle GUI at start-up */
	    int err = gui_open ();

	    if (err >= 0) {
		do {
		    gui_handle_events ();

		    uae_msleep (10);

		} while (!uae_state_change_pending ());
	    } else if (err == - 1) {
		if (restart_program == 3) {
		    restart_program = 0;
		    uae_quit ();
		}
	    } else
		uae_quit ();

	    currprefs = changed_prefs;
	    fix_options ();
	    inputdevice_init ();
	}

	restart_program = 0;

	if (uae_target_state == UAE_STATE_QUITTING)
	    break;

	uae_target_state = UAE_STATE_COLD_START;

	/* Start emulator proper. */
	if (!do_init_machine ())
	    break;

	while (uae_target_state != UAE_STATE_QUITTING && uae_target_state != UAE_STATE_STOPPED) {
	    /* Reset */
	    set_state (uae_target_state);
	    do_reset_machine (uae_state == UAE_STATE_COLD_START);

	    /* Running */
	    uae_target_state = UAE_STATE_RUNNING;

	    /*
	     * Main Loop
	     */
	    do {
		set_state (uae_target_state);

		/* Run emulator. */
		do_run_machine ();

		if (uae_target_state == UAE_STATE_PAUSED) {
		    /* Paused */
		    set_state (uae_target_state);

		    audio_pause ();

		    /* While UAE is paused we have to handle
		     * input events, etc. ourselves.
		     */
		    do {
			gui_handle_events ();
			handle_events ();

			/* Manually pump input device */
			inputdevicefunc_keyboard.read ();
			inputdevicefunc_mouse.read ();
			inputdevicefunc_joystick.read ();
			inputdevice_handle_inputcode ();

			/* Don't busy wait. */
			uae_msleep (10);

		    } while (!uae_state_change_pending ());

		    audio_resume ();
		}

	    } while (uae_target_state == UAE_STATE_RUNNING);

	    /*
	     * End of Main Loop
	     *
	     * We're no longer running or paused.
	     */

	    set_inhibit_frame (IHF_QUIT_PROGRAM);

#ifdef FILESYS
	    /* Ensure any cached changes to virtual filesystem are flushed before
	     * resetting or exitting. */
	    filesys_prepare_reset ();
#endif

	} /* while (!QUITTING && !STOPPED) */

	do_exit_machine ();

	/* TODO: This stuff is a hack. What we need to do is
	 * check whether a config GUI is available. If not,
	 * then quit.
	 */
	restart_program = 3;
    }
    zfile_exit ();
}
Exemple #11
0
void SACM_Resume(void) {
	audio_resume(&__gaudio);
}
Exemple #12
0
static void *cpu_thread(void *dummyptr) {

#ifndef NDEBUG // Spamsung Galaxy Y running Gingerbread triggers this, wTf?!
    ASSERT_ON_CPU_THREAD();
#endif

    LOG("cpu_thread : initialized...");

    struct timespec deltat = { 0 };
    struct timespec disk_motor_time = { 0 };
    struct timespec t0 = { 0 }; // the target timer
    struct timespec ti = { 0 }; // actual before time sample
    struct timespec tj = { 0 }; // actual after time sample
    bool negative = false;
    long drift_adj_nsecs = 0;   // generic drift adjustment between target and actual

    int debugging_cycles = 0;

    unsigned long dbg_ticks = 0;
#if DEBUG_TIMING
    int speaker_neg_feedback = 0;
    int speaker_pos_feedback = 0;
    unsigned long dbg_cycles_executed = 0;
#endif

    audio_init();
    speaker_init();
    MB_Initialize();

    run_args.emul_reinitialize = 1;

cpu_runloop:
    do {
        LOG("CPUTHREAD %lu LOCKING FOR MAYBE INITIALIZING AUDIO ...", (unsigned long)cpu_thread_id);
        pthread_mutex_lock(&interface_mutex);
        if (emul_reinitialize_audio) {
            emul_reinitialize_audio = false;

            speaker_destroy();
            extern void MB_SoftDestroy(void);
            MB_SoftDestroy();
            audio_shutdown();

            audio_init();
            speaker_init();
            extern void MB_SoftInitialize(void);
            MB_SoftInitialize();
        }
        pthread_mutex_unlock(&interface_mutex);
        LOG("UNLOCKING FOR MAYBE INITIALIZING AUDIO ...");

        if (run_args.emul_reinitialize) {
            reinitialize();
        }

        LOG("cpu_thread : begin main loop ...");

        clock_gettime(CLOCK_MONOTONIC, &t0);

        do {
            ////SCOPE_TRACE_CPU("CPU mainloop");

            // -LOCK----------------------------------------------------------------------------------------- SAMPLE ti
            if (UNLIKELY(emul_pause_audio)) {
                emul_pause_audio = false;
                audio_pause();
            }
            pthread_mutex_lock(&interface_mutex);
            if (UNLIKELY(emul_resume_audio)) {
                emul_resume_audio = false;
                audio_resume();
            }
            if (UNLIKELY(emul_video_dirty)) {
                emul_video_dirty = false;
                video_setDirty(A2_DIRTY_FLAG);
            }
            clock_gettime(CLOCK_MONOTONIC, &ti);

            deltat = timespec_diff(t0, ti, &negative);
            if (deltat.tv_sec) {
                if (!is_fullspeed) {
                    TIMING_LOG("NOTE : serious divergence from target time ...");
                }
                t0 = ti;
                deltat = timespec_diff(t0, ti, &negative);
            }
            t0 = timespec_add(t0, EXECUTION_PERIOD_NSECS); // expected interval
            drift_adj_nsecs = negative ? ~deltat.tv_nsec : deltat.tv_nsec;

            // set up increment & decrement counters
            run_args.cpu65_cycles_to_execute = (cycles_persec_target / 1000); // cycles_persec_target * EXECUTION_PERIOD_NSECS / NANOSECONDS_PER_SECOND
            if (!is_fullspeed) {
                run_args.cpu65_cycles_to_execute += cycles_speaker_feedback;
            }
            if (run_args.cpu65_cycles_to_execute < 0) {
                run_args.cpu65_cycles_to_execute = 0;
            }

            MB_StartOfCpuExecute();
            if (is_debugging) {
                debugging_cycles = run_args.cpu65_cycles_to_execute;
            }

            do {
                if (is_debugging) {
                    run_args.cpu65_cycles_to_execute = 1;
                }

                run_args.cpu65_cycle_count = 0;
                cycles_checkpoint_count = 0;

                cpu65_run(&run_args); // run emulation for cpu65_cycles_to_execute cycles ...

#if DEBUG_TIMING
                dbg_cycles_executed += run_args.cpu65_cycle_count;
#endif

                if (is_debugging) {
                    debugging_cycles -= run_args.cpu65_cycle_count;
                    timing_checkpointCycles();

                    if (c_debugger_should_break() || (debugging_cycles <= 0)) {
                        int err = 0;
                        if ((err = pthread_cond_signal(&dbg_thread_cond))) {
                            LOG("pthread_cond_signal : %d", err);
                        }
                        if ((err = pthread_cond_wait(&cpu_thread_cond, &interface_mutex))) {
                            LOG("pthread_cond_wait : %d", err);
                        }
                        if (debugging_cycles <= 0) {
                            break;
                        }
                    }

                    if (run_args.emul_reinitialize) {
                        pthread_mutex_unlock(&interface_mutex);
                        goto cpu_runloop;
                    }
                }
            } while (is_debugging);

            MB_UpdateCycles();
            // TODO : modularize MB and other peripheral card cycles/interrupts ...

            speaker_flush(); // play audio

            TRACE_CPU_BEGIN("advance scanner");
            video_scannerUpdate();
            TRACE_CPU_END();

            clock_gettime(CLOCK_MONOTONIC, &tj);
            pthread_mutex_unlock(&interface_mutex);
            // -UNLOCK--------------------------------------------------------------------------------------- SAMPLE tj

            if (timing_shouldAutoAdjustSpeed() && !is_fullspeed) {
                disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative);
                if (UNLIKELY(negative)) {
                    LOG("WHOA... time went backwards #1! Did you just cross a timezone?");
                    disk_motor_time.tv_sec = 1;
                }
                if (!speaker_isActive() && !video_isDirty(A2_DIRTY_FLAG) && (disk6.disk[disk6.drive].file_name != NULL) &&
                    !disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS) )
                {
                    TIMING_LOG("auto switching to full speed");
                    _timing_initialize(CPU_SCALE_FASTEST);
                }
            }

            if (!is_fullspeed) {
                deltat = timespec_diff(ti, tj, &negative);
                if (UNLIKELY(negative)) {
                    LOG("WHOA... time went backwards #2! Did you just cross a timezone?");
                    deltat.tv_sec = 1;
                }
                long sleepfor = 0;
                if (LIKELY(!deltat.tv_sec))
                {
                    sleepfor = EXECUTION_PERIOD_NSECS - drift_adj_nsecs - deltat.tv_nsec;
                }

                if (sleepfor <= 0)
                {
                    // lagging ...
                    static time_t throttle_warning = 0;
                    if (t0.tv_sec - throttle_warning > 0)
                    {
                        TIMING_LOG("not sleeping to catch up ... %ld . %ld", deltat.tv_sec, deltat.tv_nsec);
                        throttle_warning = t0.tv_sec;
                    }
                }
                else
                {
                    deltat.tv_sec = 0;
                    deltat.tv_nsec = sleepfor;
                    ////TRACE_CPU_BEGIN("sleep");
                    nanosleep(&deltat, NULL);
                    ////TRACE_CPU_END();
                }

#if DEBUG_TIMING
                // collect timing statistics
                if (speaker_neg_feedback > cycles_speaker_feedback)
                {
                    speaker_neg_feedback = cycles_speaker_feedback;
                }
                if (speaker_pos_feedback < cycles_speaker_feedback)
                {
                    speaker_pos_feedback = cycles_speaker_feedback;
                }

                if ((dbg_ticks % NANOSECONDS_PER_SECOND) == 0)
                {
                    TIMING_LOG("tick:(%ld.%ld) real:(%ld.%ld) cycles exe: %d ... speaker feedback: %d/%d", t0.tv_sec, t0.tv_nsec, ti.tv_sec, ti.tv_nsec, dbg_cycles_executed, speaker_neg_feedback, speaker_pos_feedback);
                    dbg_cycles_executed = 0;
                    speaker_neg_feedback = 0;
                    speaker_pos_feedback = 0;
                }
#endif
                if ((dbg_ticks % NANOSECONDS_PER_SECOND) == 0) {
                    dbg_ticks = 0;
                }
            }

            if (timing_shouldAutoAdjustSpeed() && is_fullspeed) {
                disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative);
                if (UNLIKELY(negative)) {
                    LOG("WHOA... time went backwards #3! Did you just cross a timezone?");
                    disk_motor_time.tv_sec = 1;
                }
                if (speaker_isActive() || video_isDirty(A2_DIRTY_FLAG) ||
                    (disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS)) )
                {
                    double speed = alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor;
                    if (speed <= CPU_SCALE_FASTEST_PIVOT) {
                        TIMING_LOG("auto switching to configured speed");
                        _timing_initialize(speed);
                    }
                }
            }

            if (UNLIKELY(run_args.emul_reinitialize)) {
                break;
            }

            if (UNLIKELY(emul_reinitialize_audio)) {
                break;
            }

            if (UNLIKELY(cpu_shutting_down)) {
                break;
            }
        } while (1);

        if (UNLIKELY(cpu_shutting_down)) {
            break;
        }
    } while (1);

    speaker_destroy();
    MB_Destroy();
    audio_shutdown();

    cpu_thread_id = 0;
    cpu_pause();

    disk6_eject(0);
    disk6_eject(1);

    return NULL;
}
Exemple #13
0
static javacall_result video_resume(javacall_handle handle)
{
    return audio_resume(handle);
}
Exemple #14
0
static void *cpu_thread(void *dummyptr) {

    assert(pthread_self() == cpu_thread_id);

    LOG("cpu_thread : initialized...");

    struct timespec deltat;
#if !MOBILE_DEVICE
    struct timespec disk_motor_time;
#endif
    struct timespec t0;         // the target timer
    struct timespec ti, tj;     // actual time samples
    bool negative = false;
    long drift_adj_nsecs = 0;   // generic drift adjustment between target and actual

    int debugging_cycles0 = 0;
    int debugging_cycles = 0;

#if DEBUG_TIMING
    unsigned long dbg_ticks = 0;
    int speaker_neg_feedback = 0;
    int speaker_pos_feedback = 0;
    unsigned int dbg_cycles_executed = 0;
#endif

    do
    {
#ifdef AUDIO_ENABLED
        LOG("CPUTHREAD %lu LOCKING FOR MAYBE INITIALIZING AUDIO ...", cpu_thread_id);
        pthread_mutex_lock(&interface_mutex);
        if (emul_reinitialize_audio) {
            emul_reinitialize_audio = false;

            speaker_destroy();
            MB_Destroy();
            audio_shutdown();

            audio_init();
            speaker_init();
            MB_Initialize();
        }
        pthread_mutex_unlock(&interface_mutex);
        LOG("UNLOCKING FOR MAYBE INITIALIZING AUDIO ...");
#endif

        if (emul_reinitialize) {
            reinitialize();
        }

        LOG("cpu_thread : begin main loop ...");

        clock_gettime(CLOCK_MONOTONIC, &t0);

        do {
            SCOPE_TRACE_CPU("CPU mainloop");
            // -LOCK----------------------------------------------------------------------------------------- SAMPLE ti
#ifdef AUDIO_ENABLED
            if (UNLIKELY(emul_pause_audio)) {
                emul_pause_audio = false;
                audio_pause();
            }
#endif
            pthread_mutex_lock(&interface_mutex);
#ifdef AUDIO_ENABLED
            if (UNLIKELY(emul_resume_audio)) {
                emul_resume_audio = false;
                audio_resume();
            }
#endif
            clock_gettime(CLOCK_MONOTONIC, &ti);

            deltat = timespec_diff(t0, ti, &negative);
            if (deltat.tv_sec)
            {
                if (!is_fullspeed) {
                    TIMING_LOG("NOTE : serious divergence from target time ...");
                }
                t0 = ti;
                deltat = timespec_diff(t0, ti, &negative);
            }
            t0 = timespec_add(t0, EXECUTION_PERIOD_NSECS); // expected interval
            drift_adj_nsecs = negative ? ~deltat.tv_nsec : deltat.tv_nsec;

            // set up increment & decrement counters
            cpu65_cycles_to_execute = (cycles_persec_target / 1000); // cycles_persec_target * EXECUTION_PERIOD_NSECS / NANOSECONDS_PER_SECOND
            if (!is_fullspeed) {
                cpu65_cycles_to_execute += cycles_speaker_feedback;
            }
            if (cpu65_cycles_to_execute < 0)
            {
                cpu65_cycles_to_execute = 0;
            }

#ifdef AUDIO_ENABLED
            MB_StartOfCpuExecute();
#endif
            if (is_debugging) {
                debugging_cycles0 = cpu65_cycles_to_execute;
                debugging_cycles  = cpu65_cycles_to_execute;
            }

            do {
                if (is_debugging) {
                    cpu65_cycles_to_execute = 1;
                }

                cpu65_cycle_count = 0;
                cycles_checkpoint_count = 0;
                cpu65_run(); // run emulation for cpu65_cycles_to_execute cycles ...

                if (is_debugging) {
                    debugging_cycles -= cpu65_cycle_count;
                    if (c_debugger_should_break() || (debugging_cycles <= 0)) {
                        int err = 0;
                        if ((err = pthread_cond_signal(&dbg_thread_cond))) {
                            ERRLOG("pthread_cond_signal : %d", err);
                        }
                        if ((err = pthread_cond_wait(&cpu_thread_cond, &interface_mutex))) {
                            ERRLOG("pthread_cond_wait : %d", err);
                        }
                        if (debugging_cycles <= 0) {
                            cpu65_cycle_count = debugging_cycles0 - debugging_cycles/*<=0*/;
                            break;
                        }
                    }
                }
                if (emul_reinitialize) {
                    reinitialize();
                }
            } while (is_debugging);
#if DEBUG_TIMING
            dbg_cycles_executed += cpu65_cycle_count;
#endif
            g_dwCyclesThisFrame += cpu65_cycle_count;

#ifdef AUDIO_ENABLED
            MB_UpdateCycles(); // update 6522s (NOTE: do this before updating cycles_count_total)
#endif

            timing_checkpoint_cycles();
#if CPU_TRACING
            cpu65_trace_checkpoint();
#endif

#ifdef AUDIO_ENABLED
            speaker_flush(); // play audio
#endif

            if (g_dwCyclesThisFrame >= dwClksPerFrame) {
                g_dwCyclesThisFrame -= dwClksPerFrame;
#ifdef AUDIO_ENABLED
                MB_EndOfVideoFrame();
#endif
            }

            clock_gettime(CLOCK_MONOTONIC, &tj);
            pthread_mutex_unlock(&interface_mutex);
            // -UNLOCK--------------------------------------------------------------------------------------- SAMPLE tj

#if !MOBILE_DEVICE
            if (timing_shouldAutoAdjustSpeed()) {
                disk_motor_time = timespec_diff(disk6.motor_time, tj, &negative);
                assert(!negative);
                if (!is_fullspeed &&
#ifdef AUDIO_ENABLED
                        !speaker_isActive() &&
#endif
                        !video_isDirty() && (!disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS)) )
                {
                    TIMING_LOG("auto switching to full speed");
                    _timing_initialize(CPU_SCALE_FASTEST);
                }
            }
#endif

            if (!is_fullspeed) {
                deltat = timespec_diff(ti, tj, &negative);
                assert(!negative);
                long sleepfor = 0;
                if (!deltat.tv_sec)
                {
                    sleepfor = EXECUTION_PERIOD_NSECS - drift_adj_nsecs - deltat.tv_nsec;
                }

                if (sleepfor <= 0)
                {
                    // lagging ...
                    static time_t throttle_warning = 0;
                    if (t0.tv_sec - throttle_warning > 0)
                    {
                        TIMING_LOG("not sleeping to catch up ... %ld . %ld", deltat.tv_sec, deltat.tv_nsec);
                        throttle_warning = t0.tv_sec;
                    }
                }
                else
                {
                    deltat.tv_sec = 0;
                    deltat.tv_nsec = sleepfor;
                    TRACE_CPU_BEGIN("sleep");
                    nanosleep(&deltat, NULL);
                    TRACE_CPU_END();
                }

#if DEBUG_TIMING
                // collect timing statistics
                if (speaker_neg_feedback > cycles_speaker_feedback)
                {
                    speaker_neg_feedback = cycles_speaker_feedback;
                }
                if (speaker_pos_feedback < cycles_speaker_feedback)
                {
                    speaker_pos_feedback = cycles_speaker_feedback;
                }

                dbg_ticks += EXECUTION_PERIOD_NSECS;
                if ((dbg_ticks % NANOSECONDS_PER_SECOND) == 0)
                {
                    TIMING_LOG("tick:(%ld.%ld) real:(%ld.%ld) cycles exe: %d ... speaker feedback: %d/%d", t0.tv_sec, t0.tv_nsec, ti.tv_sec, ti.tv_nsec, dbg_cycles_executed, speaker_neg_feedback, speaker_pos_feedback);
                    dbg_cycles_executed = 0;
                    dbg_ticks = 0;
                    speaker_neg_feedback = 0;
                    speaker_pos_feedback = 0;
                }
#endif
            }

#if !MOBILE_DEVICE
            if (timing_shouldAutoAdjustSpeed()) {
                if (is_fullspeed && (
#ifdef AUDIO_ENABLED
                            speaker_isActive() ||
#endif
                            video_isDirty() || (disk6.motor_off && (disk_motor_time.tv_sec || disk_motor_time.tv_nsec > DISK_MOTOR_QUIET_NSECS))) )
                {
                    double speed = alt_speed_enabled ? cpu_altscale_factor : cpu_scale_factor;
                    if (speed < CPU_SCALE_FASTEST) {
                        TIMING_LOG("auto switching to configured speed");
                        _timing_initialize(speed);
                    }
                }
            }
#endif

            if (UNLIKELY(emul_reinitialize)) {
                break;
            }

#ifdef AUDIO_ENABLED
            if (UNLIKELY(emul_reinitialize_audio)) {
                break;
            }
#endif

            if (UNLIKELY(cpu_shutting_down)) {
                break;
            }
        } while (1);

        if (UNLIKELY(cpu_shutting_down)) {
            break;
        }
    } while (1);

#ifdef AUDIO_ENABLED
    speaker_destroy();
    MB_Destroy();
    audio_shutdown();
#endif

    return NULL;
}