Esempio n. 1
0
void adlib_io_write_base(ioport_t port, Bit8u value)
{
    adlib_time_last = GETusTIME(0);
#ifdef HAS_YMF262
    YMF262Write(opl3, port, value);
#endif
}
Esempio n. 2
0
void adlib_timer(void)
{
#ifdef HAS_YMF262
    int i, nsamps;
    double period;
    long long now = GETusTIME(0);

    if (adlib_time_cur - adlib_time_last > ADLIB_THRESHOLD) {
	ADLIB_STOP();
	pcm_flush(adlib_strm);
    }
    if (ADLIB_RUNNING()) {
	period = pcm_samp_period(opl3_rate, 2);
	nsamps = (now - adlib_time_cur) / period;
	if (nsamps > OPL3_MAX_BUF)
	    nsamps = OPL3_MAX_BUF;
	nsamps -= nsamps % 2;
	if (nsamps) {
	    adlib_process_samples(nsamps / 2);
	    adlib_time_cur += nsamps * period;
	    S_printf("SB: processed %i Adlib samples\n", nsamps);
	}
    }

    for (i = 0; i < 2; i++) {
	if (opl3_timers[i] > 0 && now > opl3_timers[i]) {
	    S_printf("Adlib: timer %i expired\n", i);
	    opl3_timers[i] = 0;
	    YMF262TimerOver(opl3, i);
	}
    }
#endif
}
Esempio n. 3
0
void rtc_run(void)
{
  static hitimer_t last_time = -1;
  int rate;
  hitimer_t ticks_m, cur_time = GETusTIME(0);
  if (last_time == -1 || last_time > cur_time) {
    last_time = cur_time;
    return;
  }
  rate = rtc_get_rate(GET_CMOS(CMOS_STATUSA) & 0x0f);
  ticks_m = (cur_time - last_time) * rate;
  q_ticks_m += ticks_m;
  last_time = cur_time;
  if (debug_level('h') > 8)
    h_printf("RTC: A=%hhx B=%hhx C=%hhx rate=%i queued=%lli added=%lli\n",
	GET_CMOS(CMOS_STATUSA), GET_CMOS(CMOS_STATUSB), GET_CMOS(CMOS_STATUSC),
	rate, (long long)q_ticks_m, (long long)ticks_m);
  if (q_ticks_m >= 1000000) {
    Bit8u old_c = GET_CMOS(CMOS_STATUSC);
    SET_CMOS(CMOS_STATUSC, old_c | 0x40);
    if ((GET_CMOS(CMOS_STATUSB) & 0x40) && !(GET_CMOS(CMOS_STATUSC) & 0x80)) {
      SET_CMOS(CMOS_STATUSC, GET_CMOS(CMOS_STATUSC) | 0x80);
      if (debug_level('h') > 7)
        h_printf("RTC: periodic IRQ, queued=%lli, added=%lli\n",
	    (long long)q_ticks_m, (long long)ticks_m);
      pic_request(PIC_IRQ8);
    }
    if (!(old_c & 0x40))
      q_ticks_m -= 1000000;
  }
}
Esempio n. 4
0
static void opl3_set_timer(void *param, int num, double interval_Sec)
{
    long long *timers = param;
    timers[num] =
	interval_Sec > 0 ? GETusTIME(0) + interval_Sec * 1000000 : 0;
    S_printf("Adlib: timer %i set to %ius\n", num,
	     (int) (interval_Sec * 1000000));
}
Esempio n. 5
0
static void midoflus_start(void)
{
    S_printf("MIDI: starting fluidsynth\n");
    mf_time_base = GETusTIME(0);
    pthread_mutex_lock(&syn_mtx);
    pcm_prepare_stream(pcm_stream);
    fluid_sequencer_process(sequencer, 0);
    output_running = 1;
    pthread_mutex_unlock(&syn_mtx);
}
Esempio n. 6
0
static void nullsnd_timer(void)
{
    double time, frag_time;
    if (!running || locked)
        return;
    frag_time = pcm_frag_period(frag_size, &params);
    time = GETusTIME(0);
    while (time - last_time > frag_time) {
        last_time += frag_time;
        calls.get_data(NULL, frag_size, &params);
    }
}
Esempio n. 7
0
static void midoflus_write(unsigned char val)
{
    int ret;
    unsigned long long now = GETusTIME(0);
    int msec = (now - mf_time_base) / 1000;

    if (!output_running)
	midoflus_start();

    fluid_sequencer_process(sequencer, msec);
    ret = fluid_sequencer_add_midi_data_to_buffer(synthSeqID, &val, 1);
    if (ret != FLUID_OK)
	S_printf("MIDI: failed sending midi event\n");
}
Esempio n. 8
0
static void *synth_thread(void *arg)
{
    while (1) {
	sem_wait(&syn_sem);
	pthread_mutex_lock(&syn_mtx);
	if (!output_running) {
		pthread_mutex_unlock(&syn_mtx);
		continue;
	}
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
	process_samples(GETusTIME(0), FLUS_MIN_BUF);
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_mutex_unlock(&syn_mtx);
    }
    return NULL;
}
Esempio n. 9
0
static void dspio_start_input(struct dspio_state *state)
{
    if (state->input_running)
	return;
    S_printf("SB: starting input\n");
    state->input_time_cur = GETusTIME(0);
    state->input_running = 1;
    if (!state->dma.rate) {
	S_printf("SB: not starting recorder\n");
	return;
    }
    if (!state->pcm_input_running) {
	pcm_reset_player(state->i_handle);
	state->pcm_input_running = 1;
    }
}
Esempio n. 10
0
//Read the current timer state, will use current double
static Bit8u AdlibChip__Read(AdlibTimer *timer) {
	long long time = GETusTIME(0);
	AdlibTimer__Update(&timer[0], time);
	AdlibTimer__Update(&timer[1], time);
	Bit8u ret = 0;
	//Overflow won't be set if a channel is masked
	if ( timer[0].overflow ) {
		ret |= 0x40;
		ret |= 0x80;
	}
	if ( timer[1].overflow ) {
		ret |= 0x20;
		ret |= 0x80;
	}
	return ret;

}
Esempio n. 11
0
static int dspio_run_dma(struct dspio_state *state)
{
#define DMA_TIMEOUT_US 100000
    int ret;
    struct dspio_dma *dma = &state->dma;
    hitimer_t now = GETusTIME(0);
    sb_dma_processing();	// notify that DMA busy
    ret = do_run_dma(state);
    if (ret) {
	sb_handle_dma();
	dma->time_cur = now;
    } else if (now - dma->time_cur > DMA_TIMEOUT_US) {
	S_printf("SB: Warning: DMA busy for too long, releasing\n");
//	error("SB: DMA timeout\n");
	sb_handle_dma_timeout();
    }
    return ret;
}
Esempio n. 12
0
void dspio_start_dma(void *dspio)
{
    int dma_cnt = 0;
    DSPIO->dma.running = 1;
    DSPIO->dma.time_cur = GETusTIME(0);
    get_dma_params(&DSPIO->dma);

    if (DSPIO->dma.input) {
	dspio_start_input(DSPIO);
    } else {
	dma_cnt = dspio_fill_output(DSPIO);
	if (DSPIO->dma.running && dspio_output_fifo_filled(DSPIO))
	    S_printf("SB: Output filled, processed %i DMA cycles\n",
		     dma_cnt);
	else
	    S_printf("SB: Output fillup incomplete (%i %i %i)\n",
		     DSPIO->dma.running, DSPIO->output_running, dma_cnt);
    }
}
Esempio n. 13
0
static void midoflus_stop(void *arg)
{
    long long now;
    int msec;
    if (!output_running)
	return;
    now = GETusTIME(0);
    msec = (now - mf_time_base) / 1000;
    S_printf("MIDI: stopping fluidsynth at msec=%i\n", msec);
    pthread_mutex_lock(&syn_mtx);
    /* advance past last event */
    fluid_sequencer_process(sequencer, msec);
    /* shut down all active notes */
    fluid_synth_system_reset(synth);
    if (pcm_running)
	pcm_flush(pcm_stream);
    pcm_running = 0;
    output_running = 0;
    pthread_mutex_unlock(&syn_mtx);
}
Esempio n. 14
0
//Check for it being a write to the timer
static bool AdlibChip__WriteTimer(AdlibTimer *timer, Bit32u reg, Bit8u val) {
	switch ( reg ) {
	case 0x02:
		timer[0].counter = val;
		return true;
	case 0x03:
		timer[1].counter = val;
		return true;
	case 0x04: {
		long long time = GETusTIME(0);
		if ( val & 0x80 ) {
			AdlibTimer__Reset(&timer[0], time);
			AdlibTimer__Reset(&timer[1], time);
		} else {
			AdlibTimer__Update(&timer[0], time);
			AdlibTimer__Update(&timer[1], time);
			if ( val & 0x1 ) {
				AdlibTimer__Start(&timer[0], time, 80);
				S_printf("Adlib: timer 0 set to %lluus\n",
						timer[0].delay);
			} else {
				AdlibTimer__Stop(&timer[0]);
			}
			timer[0].masked = (val & 0x40) > 0;
			if ( timer[0].masked )
				timer[0].overflow = false;
			if ( val & 0x2 ) {
				AdlibTimer__Start(&timer[1], time, 320);
				S_printf("Adlib: timer 1 set to %lluus\n",
						timer[1].delay);
			} else {
				AdlibTimer__Stop(&timer[1]);
			}
			timer[1].masked = (val & 0x20) > 0;
			if ( timer[1].masked )
				timer[1].overflow = false;
		}
		return true; }
	}
	return false;
}
Esempio n. 15
0
static void dspio_process_dma(struct dspio_state *state)
{
    int dma_cnt, nfr, in_fifo_cnt, out_fifo_cnt, i, j, tlocked;
    unsigned long long time_dst;
    double output_time_cur;
    sndbuf_t buf[PCM_MAX_BUF][SNDBUF_CHANS];
    static int warned;

    dma_cnt = in_fifo_cnt = out_fifo_cnt = 0;

    if (state->dma.running) {
	state->dma.stereo = sb_dma_samp_stereo();
	state->dma.rate = sb_get_dma_sampling_rate();
	state->dma.samp_signed = sb_dma_samp_signed();
	state->dma.dsp_fifo_enabled = sb_fifo_enabled();
	dma_cnt += state->dma.input ? dspio_drain_input(state) :
	    dspio_fill_output(state);
    }

    if (!state->output_running && !state->input_running)
	return;

    time_dst = GETusTIME(0);
    if (state->output_running) {
	output_time_cur = pcm_time_lock(state->dma_strm);
	tlocked = 1;
	nfr = calc_nframes(state, output_time_cur, time_dst);
    } else {
	nfr = 0;
	tlocked = 0;
    }
    for (i = 0; i < nfr; i++) {
	for (j = 0; j < state->dma.stereo + 1; j++) {
	    if (state->dma.running && !dspio_output_fifo_filled(state)) {
		if (!dspio_run_dma(state))
		    break;
		dma_cnt++;
	    }
	    if (!dspio_get_output_sample(state, &buf[i][j],
		    state->dma.is16bit))
		break;
#if 0
	    /* if speaker disabled, overwrite DMA data with silence */
	    /* on SB16 is not used */
	    if (!state->speaker)
		dma_get_silence(state->dma.samp_signed,
			state->dma.is16bit, &buf[i][j]);
#endif
	}
	if (j != state->dma.stereo + 1)
	    break;
	out_fifo_cnt++;
    }
    if (out_fifo_cnt && state->dma.rate) {
	pcm_write_interleaved(buf, out_fifo_cnt, state->dma.rate,
			  pcm_get_format(state->dma.is16bit,
					 state->dma.samp_signed),
			  state->dma.stereo + 1, state->dma_strm);
	output_time_cur = pcm_get_stream_time(state->dma_strm);
	if (state->dma.running && output_time_cur > time_dst - 1) {
	    pcm_clear_flag(state->dma_strm, PCM_FLAG_POST);
	    warned = 0;
	}
    }
    if (out_fifo_cnt < nfr) {
	/* not enough samples, see why */
	if (!sb_dma_active()) {
	    dspio_stop_output(state);
	} else {
	    if (nfr && !warned) {
		S_printf("SB: Output FIFO exhausted while DMA is still active (ol=%f)\n",
			 time_dst - output_time_cur);
		warned = 1;
	    }
	    if (state->dma.running)
		S_printf("SB: Output FIFO exhausted while DMA is running (no DACK?)\n");
	    /* DMA is active but currently not running and the FIFO is
	     * already exhausted. Normally we should flush the channel
	     * and stop the output timing.
	     * HACK: try to not flush the channel for as long as possible
	     * in a hope the PCM buffers are large enough to hold till
	     * the DMA is restarted. */
	    pcm_set_flag(state->dma_strm, PCM_FLAG_POST);
	    /* awake dosemu */
	    reset_idle(0);
	}
    }
    if (tlocked)
	pcm_time_unlock(state->dma_strm);

    /* TODO: sync also input time with PCM? */
    if (state->input_running)
	nfr = calc_nframes(state, state->input_time_cur, time_dst);
    else
	nfr = 0;
    if (nfr && state->i_started && sb_input_enabled()) {
	struct player_params params;
	params.rate = state->dma.rate;
	params.channels = state->dma.stereo + 1;
	params.format = pcm_get_format(state->dma.is16bit,
		state->dma.samp_signed);
	params.handle = state->i_handle;
	nfr = pcm_data_get_interleaved(buf, nfr, &params);
    }
    if (!state->i_started) {
	for (i = 0; i < nfr; i++) {
	    for (j = 0; j < state->dma.stereo + 1; j++)
		dma_get_silence(state->dma.samp_signed,
			state->dma.is16bit, &buf[i][j]);
	}
    }
    for (i = 0; i < nfr; i++) {
	for (j = 0; j < state->dma.stereo + 1; j++) {
	    if (sb_input_enabled()) {
		if (!dspio_put_input_sample(state, &buf[i][j],
			state->dma.is16bit))
		    break;
	    }
	}
	if (j == state->dma.stereo + 1)
	    in_fifo_cnt++;
	for (j = 0; j < state->dma.stereo + 1; j++) {
	    if (state->dma.running) {
		if (!dspio_run_dma(state))
		    break;
		dma_cnt++;
	    }
	}
	if (!state->input_running || (j != state->dma.stereo + 1))
	    break;
    }
    if (in_fifo_cnt) {
	if (state->dma.rate) {
	    state->input_time_cur += in_fifo_cnt *
		    pcm_frame_period_us(state->dma.rate);
	} else {
	    state->input_time_cur = time_dst;
	}
    }

    if (debug_level('S') >= 7 && (in_fifo_cnt || out_fifo_cnt || dma_cnt))
	S_printf("SB: Processed %i %i FIFO, %i DMA, or=%i dr=%i\n",
	     in_fifo_cnt, out_fifo_cnt, dma_cnt, state->output_running, state->dma.running);
}
Esempio n. 16
0
static void nullsnd_start(void)
{
    last_time = GETusTIME(0);
    running = 1;
}
Esempio n. 17
0
void dspio_stop_midi(void *dspio)
{
    DSPIO->midi_time_cur = GETusTIME(0);
    midi_stop();
}
Esempio n. 18
0
Bit32u dspio_get_midi_in_time(void *dspio)
{
    Bit32u delta = GETusTIME(0) - DSPIO->midi_time_cur;
    S_printf("SB: midi clock, delta=%i\n", delta);
    return delta;
}