/*
 * QEMU Proxy for OPL2/3 emulation by MAME team
 *
 * Copyright (c) 2004-2005 Vassili Karpov (malc)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "hw/hw.h"
#include "hw/audio/audio.h"
#include "audio/audio.h"
#include "hw/isa/isa.h"

//#define DEBUG

#define ADLIB_KILL_TIMERS 1

#ifdef DEBUG
#include "qemu/timer.h"
#endif

#define dolog(...) AUD_log ("adlib", __VA_ARGS__)
#ifdef DEBUG
#define ldebug(...) dolog (__VA_ARGS__)
#else
#define ldebug(...)
#endif

#ifdef HAS_YMF262
#include "ymf262.h"
void YMF262UpdateOneQEMU (int which, INT16 *dst, int length);
#define SHIFT 2
#else
#include "fmopl.h"
#define SHIFT 1
#endif

#define IO_READ_PROTO(name) \
    uint32_t name (void *opaque, uint32_t nport)
#define IO_WRITE_PROTO(name) \
    void name (void *opaque, uint32_t nport, uint32_t val)

static struct {
    int port;
    int freq;
} conf = {0x220, 44100};

typedef struct {
    QEMUSoundCard card;
    int ticking[2];
    int enabled;
    int active;
    int bufpos;
#ifdef DEBUG
    int64_t exp[2];
#endif
    int16_t *mixbuf;
    uint64_t dexp[2];
    SWVoiceOut *voice;
    int left, pos, samples;
    QEMUAudioTimeStamp ats;
#ifndef HAS_YMF262
    FM_OPL *opl;
#endif
} AdlibState;

static AdlibState glob_adlib;

static void adlib_stop_opl_timer (AdlibState *s, size_t n)
{
#ifdef HAS_YMF262
    YMF262TimerOver (0, n);
#else
    OPLTimerOver (s->opl, n);
#endif
    s->ticking[n] = 0;
}

static void adlib_kill_timers (AdlibState *s)
{
    size_t i;

    for (i = 0; i < 2; ++i) {
        if (s->ticking[i]) {
            uint64_t delta;

            delta = AUD_get_elapsed_usec_out (s->voice, &s->ats);
            ldebug (
                "delta = %f dexp = %f expired => %d\n",
                delta / 1000000.0,
                s->dexp[i] / 1000000.0,
                delta >= s->dexp[i]
                );
            if (ADLIB_KILL_TIMERS || delta >= s->dexp[i]) {
                adlib_stop_opl_timer (s, i);
                AUD_init_time_stamp_out (s->voice, &s->ats);
            }
        }
    }
}

static IO_WRITE_PROTO (adlib_write)
{
    AdlibState *s = opaque;
    int a = nport & 3;

    s->active = 1;
    AUD_set_active_out (s->voice, 1);

    adlib_kill_timers (s);

#ifdef HAS_YMF262
    YMF262Write (0, a, val);
#else
    OPLWrite (s->opl, a, val);
#endif
}

static IO_READ_PROTO (adlib_read)
{
    AdlibState *s = opaque;
    uint8_t data;
    int a = nport & 3;

    adlib_kill_timers (s);

#ifdef HAS_YMF262
    data = YMF262Read (0, a);
#else
    data = OPLRead (s->opl, a);
#endif
    return data;
}

static void timer_handler (int c, double interval_Sec)
{
    AdlibState *s = &glob_adlib;
    unsigned n = c & 1;
#ifdef DEBUG
    double interval;
    int64_t exp;
#endif

    if (interval_Sec == 0.0) {
        s->ticking[n] = 0;
        return;
    }

    s->ticking[n] = 1;
#ifdef DEBUG
    interval = get_ticks_per_sec () * interval_Sec;
    exp = qemu_get_clock_ns (vm_clock) + interval;
    s->exp[n] = exp;
#endif

    s->dexp[n] = interval_Sec * 1000000.0;
    AUD_init_time_stamp_out (s->voice, &s->ats);
}

static int write_audio (AdlibState *s, int samples)
{
    int net = 0;
    int pos = s->pos;

    while (samples) {
        int nbytes, wbytes, wsampl;

        nbytes = samples << SHIFT;
        wbytes = AUD_write (
            s->voice,
            s->mixbuf + (pos << (SHIFT - 1)),
            nbytes
            );

        if (wbytes) {
            wsampl = wbytes >> SHIFT;

            samples -= wsampl;
            pos = (pos + wsampl) % s->samples;

            net += wsampl;
        }
        else {
            break;
        }
    }

    return net;
}

static void adlib_callback (void *opaque, int free)
{
    AdlibState *s = opaque;
    int samples, net = 0, to_play, written;

    samples = free >> SHIFT;
    if (!(s->active && s->enabled) || !samples) {
        return;
    }

    to_play = audio_MIN (s->left, samples);
    while (to_play) {
        written = write_audio (s, to_play);

        if (written) {
            s->left -= written;
            samples -= written;
            to_play -= written;
            s->pos = (s->pos + written) % s->samples;
        }
        else {
            return;
        }
    }

    samples = audio_MIN (samples, s->samples - s->pos);
    if (!samples) {
        return;
    }

#ifdef HAS_YMF262
    YMF262UpdateOneQEMU (0, s->mixbuf + s->pos * 2, samples);
#else
    YM3812UpdateOne (s->opl, s->mixbuf + s->pos, samples);
#endif

    while (samples) {
        written = write_audio (s, samples);

        if (written) {
            net += written;
            samples -= written;
            s->pos = (s->pos + written) % s->samples;
        }
        else {
            s->left = samples;
            return;
        }
    }
}

static void Adlib_fini (AdlibState *s)
{
#ifdef HAS_YMF262
    YMF262Shutdown ();
#else
    if (s->opl) {
        OPLDestroy (s->opl);
        s->opl = NULL;
    }
#endif

    if (s->mixbuf) {
        g_free (s->mixbuf);
    }

    s->active = 0;
    s->enabled = 0;
    AUD_remove_card (&s->card);
}

int Adlib_init (ISABus *bus)
{
    AdlibState *s = &glob_adlib;
    struct audsettings as;

#ifdef HAS_YMF262
    if (YMF262Init (1, 14318180, conf.freq)) {
        dolog ("YMF262Init %d failed\n", conf.freq);
        return -1;
    }
    else {
        YMF262SetTimerHandler (0, timer_handler, 0);
        s->enabled = 1;
    }
#else
    s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq);
    if (!s->opl) {
        dolog ("OPLCreate %d failed\n", conf.freq);
        return -1;
    }
    else {
        OPLSetTimerHandler (s->opl, timer_handler, 0);
        s->enabled = 1;
    }
#endif

    as.freq = conf.freq;
    as.nchannels = SHIFT;
    as.fmt = AUD_FMT_S16;
    as.endianness = AUDIO_HOST_ENDIANNESS;

    AUD_register_card ("adlib", &s->card);

    s->voice = AUD_open_out (
        &s->card,
        s->voice,
        "adlib",
        s,
        adlib_callback,
        &as
        );
    if (!s->voice) {
        Adlib_fini (s);
        return -1;
    }

    s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
    s->mixbuf = g_malloc0 (s->samples << SHIFT);

    register_ioport_read (0x388, 4, 1, adlib_read, s);
    register_ioport_write (0x388, 4, 1, adlib_write, s);

    register_ioport_read (conf.port, 4, 1, adlib_read, s);
    register_ioport_write (conf.port, 4, 1, adlib_write, s);

    register_ioport_read (conf.port + 8, 2, 1, adlib_read, s);
    register_ioport_write (conf.port + 8, 2, 1, adlib_write, s);

    return 0;
}
