/*
 * QEMU Apple Sound Chip emulation
 *
 * Apple Sound Chip (ASC) 344S0063
 * Enhanced Apple Sound Chip (EASC) 343S1063
 *
 * Copyright (c) 2012-2018 Laurent Vivier <laurent@vivier.eu>
 * Copyright (c) 2022 Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/timer.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "audio/audio.h"
#include "hw/audio/asc.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "trace.h"

/*
 * Linux doesn't provide information about ASC, see arch/m68k/mac/macboing.c
 * and arch/m68k/include/asm/mac_asc.h
 *
 * best information is coming from MAME:
 *   https://github.com/mamedev/mame/blob/master/src/devices/sound/asc.h
 *   https://github.com/mamedev/mame/blob/master/src/devices/sound/asc.cpp
 *   Emulation by R. Belmont
 * or MESS:
 *   http://mess.redump.net/mess/driver_info/easc
 *
 *     0x800: VERSION
 *     0x801: MODE
 *            1=FIFO mode,
 *            2=wavetable mode
 *     0x802: CONTROL
 *            bit 0=analog or PWM output,
 *                1=stereo/mono,
 *                7=processing time exceeded
 *     0x803: FIFO MODE
 *            bit 7=clear FIFO,
 *            bit 1="non-ROM companding",
 *            bit 0="ROM companding")
 *     0x804: FIFO IRQ STATUS
 *            bit 0=ch A 1/2 full,
 *                1=ch A full,
 *                2=ch B 1/2 full,
 *                3=ch B full)
 *     0x805: WAVETABLE CONTROL
 *            bits 0-3 wavetables 0-3 start
 *     0x806: VOLUME
 *            bits 2-4 = 3 bit internal ASC volume,
 *            bits 5-7 = volume control sent to Sony sound chip
 *     0x807: CLOCK RATE
 *            0 = Mac 22257 Hz,
 *            1 = undefined,
 *            2 = 22050 Hz,
 *            3 = 44100 Hz
 *     0x80a: PLAY REC A
 *     0x80f: TEST
 *            bits 6-7 = digital test,
 *            bits 4-5 = analog test
 *     0x810: WAVETABLE 0 PHASE
 *            big-endian 9.15 fixed-point, only 24 bits valid
 *     0x814: WAVETABLE 0 INCREMENT
 *            big-endian 9.15 fixed-point, only 24 bits valid
 *     0x818: WAVETABLE 1 PHASE
 *     0x81C: WAVETABLE 1 INCREMENT
 *     0x820: WAVETABLE 2 PHASE
 *     0x824: WAVETABLE 2 INCREMENT
 *     0x828: WAVETABLE 3 PHASE
 *     0x82C: WAVETABLE 3 INCREMENT
 *     0x830: UNKNOWN START
 *            NetBSD writes Wavetable data here (are there more
 *            wavetables/channels than we know about?)
 *     0x857: UNKNOWN END
 */

#define ASC_SIZE           0x2000

enum {
    ASC_VERSION     = 0x00,
    ASC_MODE        = 0x01,
    ASC_CONTROL     = 0x02,
    ASC_FIFOMODE    = 0x03,
    ASC_FIFOIRQ     = 0x04,
    ASC_WAVECTRL    = 0x05,
    ASC_VOLUME      = 0x06,
    ASC_CLOCK       = 0x07,
    ASC_PLAYRECA    = 0x0a,
    ASC_TEST        = 0x0f,
    ASC_WAVETABLE   = 0x10
};

#define ASC_FIFO_STATUS_HALF_FULL      1
#define ASC_FIFO_STATUS_FULL_EMPTY     2

#define ASC_EXTREGS_FIFOCTRL           0x8
#define ASC_EXTREGS_INTCTRL            0x9
#define ASC_EXTREGS_CDXA_DECOMP_FILT   0x10

#define ASC_FIFO_CYCLE_TIME            ((NANOSECONDS_PER_SECOND / ASC_FREQ) * \
                                        0x400)

static void asc_raise_irq(ASCState *s)
{
    qemu_set_irq(s->irq, 1);
}

static void asc_lower_irq(ASCState *s)
{
    qemu_set_irq(s->irq, 0);
}

static uint8_t asc_fifo_get(ASCFIFOState *fs)
{
    ASCState *s = container_of(fs, ASCState, fifos[fs->index]);
    bool fifo_half_irq_enabled = fs->extregs[ASC_EXTREGS_INTCTRL] & 1;
    uint8_t val;

    assert(fs->cnt);

    val = fs->fifo[fs->rptr];
    trace_asc_fifo_get('A' + fs->index, fs->rptr, fs->cnt, val);

    fs->rptr++;
    fs->rptr &= 0x3ff;
    fs->cnt--;

    if (fs->cnt <= 0x1ff) {
        /* FIFO less than half full */
        fs->int_status |= ASC_FIFO_STATUS_HALF_FULL;
    } else {
        /* FIFO more than half full */
        fs->int_status &= ~ASC_FIFO_STATUS_HALF_FULL;
    }

    if (fs->cnt == 0x1ff && fifo_half_irq_enabled) {
        /* Raise FIFO half full IRQ */
        asc_raise_irq(s);
    }

    if (fs->cnt == 0) {
        /* Raise FIFO empty IRQ */
        fs->int_status |= ASC_FIFO_STATUS_FULL_EMPTY;
        asc_raise_irq(s);
    }

    return val;
}

static int generate_fifo(ASCState *s, int maxsamples)
{
    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    uint8_t *buf = s->mixbuf;
    int i, wcount = 0;

    while (wcount < maxsamples) {
        uint8_t val;
        int16_t d, f0, f1;
        int32_t t;
        int shift, filter;
        bool hasdata = false;

        for (i = 0; i < 2; i++) {
            ASCFIFOState *fs = &s->fifos[i];

            switch (fs->extregs[ASC_EXTREGS_FIFOCTRL] & 0x83) {
            case 0x82:
                /*
                 * CD-XA BRR mode: decompress 15 bytes into 28 16-bit
                 * samples
                 */
                if (!fs->cnt) {
                    val = 0x80;
                    break;
                }

                if (fs->xa_cnt == -1) {
                    /* Start of packet, get flags */
                    fs->xa_flags = asc_fifo_get(fs);
                    fs->xa_cnt = 0;
                }

                shift = fs->xa_flags & 0xf;
                filter = fs->xa_flags >> 4;
                f0 = (int8_t)fs->extregs[ASC_EXTREGS_CDXA_DECOMP_FILT +
                                 (filter << 1) + 1];
                f1 = (int8_t)fs->extregs[ASC_EXTREGS_CDXA_DECOMP_FILT +
                                 (filter << 1)];

                if ((fs->xa_cnt & 1) == 0) {
                    if (!fs->cnt) {
                        val = 0x80;
                        break;
                    }

                    fs->xa_val = asc_fifo_get(fs);
                    d = (fs->xa_val & 0xf) << 12;
                } else {
                    d = (fs->xa_val & 0xf0) << 8;
                }
                t = (d >> shift) + (((fs->xa_last[0] * f0) +
                                     (fs->xa_last[1] * f1) + 32) >> 6);
                if (t < -32768) {
                    t = -32768;
                } else if (t > 32767) {
                    t = 32767;
                }

                /*
                 * CD-XA BRR generates 16-bit signed output, so convert to
                 * 8-bit before writing to buffer. Does real hardware do the
                 * same?
                 */
                val = (uint8_t)(t / 256) ^ 0x80;
                hasdata = true;
                fs->xa_cnt++;

                fs->xa_last[1] = fs->xa_last[0];
                fs->xa_last[0] = (int16_t)t;

                if (fs->xa_cnt == 28) {
                    /* End of packet */
                    fs->xa_cnt = -1;
                }
                break;

            default:
                /* fallthrough */
            case 0x80:
                /* Raw mode */
                if (fs->cnt) {
                    val = asc_fifo_get(fs);
                    hasdata = true;
                } else {
                    val = 0x80;
                }
                break;
            }

            buf[wcount * 2 + i] = val;
        }

        if (!hasdata) {
            break;
        }

        wcount++;
    }

    /*
     * MacOS (un)helpfully leaves the FIFO engine running even when it has
     * finished writing out samples, but still expects the FIFO empty
     * interrupts to be generated for each FIFO cycle (without these interrupts
     * MacOS will freeze)
     */
    if (s->fifos[0].cnt == 0 && s->fifos[1].cnt == 0) {
        if (!s->fifo_empty_ns) {
            /* FIFO has completed first empty cycle */
            s->fifo_empty_ns = now;
        } else if (now > (s->fifo_empty_ns + ASC_FIFO_CYCLE_TIME)) {
            /* FIFO has completed entire cycle with no data */
            s->fifos[0].int_status |= ASC_FIFO_STATUS_HALF_FULL |
                                      ASC_FIFO_STATUS_FULL_EMPTY;
            s->fifos[1].int_status |= ASC_FIFO_STATUS_HALF_FULL |
                                      ASC_FIFO_STATUS_FULL_EMPTY;
            s->fifo_empty_ns = now;
            asc_raise_irq(s);
        }
    } else {
        /* FIFO contains data, reset empty time */
        s->fifo_empty_ns = 0;
    }

    return wcount;
}

static int generate_wavetable(ASCState *s, int maxsamples)
{
    uint8_t *buf = s->mixbuf;
    int channel, count = 0;

    while (count < maxsamples) {
        uint32_t left = 0, right = 0;
        uint8_t sample;

        for (channel = 0; channel < 4; channel++) {
            ASCFIFOState *fs = &s->fifos[channel >> 1];
            int chanreg = ASC_WAVETABLE + (channel << 3);
            uint32_t phase, incr, offset;

            phase = ldl_be_p(&s->regs[chanreg]);
            incr = ldl_be_p(&s->regs[chanreg + sizeof(uint32_t)]);

            phase += incr;
            offset = (phase >> 15) & 0x1ff;
            sample = fs->fifo[0x200 * (channel >> 1) + offset];

            stl_be_p(&s->regs[chanreg], phase);

            left += sample;
            right += sample;
        }

        buf[count * 2] = left >> 2;
        buf[count * 2 + 1] = right >> 2;

        count++;
    }

    return count;
}

static void asc_out_cb(void *opaque, int free_b)
{
    ASCState *s = opaque;
    int samples, generated;

    if (free_b == 0) {
        return;
    }

    samples = MIN(s->samples, free_b >> s->shift);

    switch (s->regs[ASC_MODE] & 3) {
    default:
        /* Off */
        generated = 0;
        break;
    case 1:
        /* FIFO mode */
        generated = generate_fifo(s, samples);
        break;
    case 2:
        /* Wave table mode */
        generated = generate_wavetable(s, samples);
        break;
    }

    if (!generated) {
        /* Workaround for audio underflow bug on Windows dsound backend */
        int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
        int silent_samples = muldiv64(now - s->fifo_empty_ns,
                                      NANOSECONDS_PER_SECOND, ASC_FREQ);

        if (silent_samples > ASC_FIFO_CYCLE_TIME / 2) {
            /*
             * No new FIFO data within half a cycle time (~23ms) so fill the
             * entire available buffer with silence. This prevents an issue
             * with the Windows dsound backend whereby the sound appears to
             * loop because the FIFO has run out of data, and the driver
             * reuses the stale content in its circular audio buffer.
             */
            AUD_write(s->voice, s->silentbuf, samples << s->shift);
        }
        return;
    }

    AUD_write(s->voice, s->mixbuf, generated << s->shift);
}

static uint64_t asc_fifo_read(void *opaque, hwaddr addr,
                              unsigned size)
{
    ASCFIFOState *fs = opaque;

    trace_asc_read_fifo('A' + fs->index, addr, size, fs->fifo[addr]);
    return fs->fifo[addr];
}

static void asc_fifo_write(void *opaque, hwaddr addr, uint64_t value,
                           unsigned size)
{
    ASCFIFOState *fs = opaque;
    ASCState *s = container_of(fs, ASCState, fifos[fs->index]);
    bool fifo_half_irq_enabled = fs->extregs[ASC_EXTREGS_INTCTRL] & 1;

    trace_asc_write_fifo('A' + fs->index, addr, size, fs->wptr, fs->cnt, value);

    if (s->regs[ASC_MODE] == 1) {
        fs->fifo[fs->wptr++] = value;
        fs->wptr &= 0x3ff;
        fs->cnt++;

        if (fs->cnt <= 0x1ff) {
            /* FIFO less than half full */
            fs->int_status |= ASC_FIFO_STATUS_HALF_FULL;
        } else {
            /* FIFO at least half full */
            fs->int_status &= ~ASC_FIFO_STATUS_HALF_FULL;
        }

        if (fs->cnt == 0x200 && fifo_half_irq_enabled) {
            /* Raise FIFO half full interrupt */
            asc_raise_irq(s);
        }

        if (fs->cnt == 0x3ff) {
            /* Raise FIFO full interrupt */
            fs->int_status |= ASC_FIFO_STATUS_FULL_EMPTY;
            asc_raise_irq(s);
        }
    } else {
        fs->fifo[addr] = value;
    }
    return;
}

static const MemoryRegionOps asc_fifo_ops = {
    .read = asc_fifo_read,
    .write = asc_fifo_write,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .endianness = DEVICE_BIG_ENDIAN,
};

static void asc_fifo_reset(ASCFIFOState *fs);

static uint64_t asc_read(void *opaque, hwaddr addr,
                         unsigned size)
{
    ASCState *s = opaque;
    uint64_t prev, value;

    switch (addr) {
    case ASC_VERSION:
        switch (s->type) {
        default:
        case ASC_TYPE_ASC:
            value = 0;
            break;
        case ASC_TYPE_EASC:
            value = 0xb0;
            break;
        }
        break;
    case ASC_FIFOIRQ:
        prev = (s->fifos[0].int_status & 0x3) |
                (s->fifos[1].int_status & 0x3) << 2;

        s->fifos[0].int_status = 0;
        s->fifos[1].int_status = 0;
        asc_lower_irq(s);
        value = prev;
        break;
    default:
        value = s->regs[addr];
        break;
    }

    trace_asc_read_reg(addr, size, value);
    return value;
}

static void asc_write(void *opaque, hwaddr addr, uint64_t value,
                      unsigned size)
{
    ASCState *s = opaque;

    switch (addr) {
    case ASC_MODE:
        value &= 3;
        if (value != s->regs[ASC_MODE]) {
            asc_fifo_reset(&s->fifos[0]);
            asc_fifo_reset(&s->fifos[1]);
            asc_lower_irq(s);
            if (value != 0) {
                AUD_set_active_out(s->voice, 1);
            } else {
                AUD_set_active_out(s->voice, 0);
            }
        }
        break;
    case ASC_FIFOMODE:
        if (value & 0x80) {
            asc_fifo_reset(&s->fifos[0]);
            asc_fifo_reset(&s->fifos[1]);
            asc_lower_irq(s);
        }
        break;
    case ASC_WAVECTRL:
        break;
    case ASC_VOLUME:
        {
            int vol = (value & 0xe0);

            AUD_set_volume_out(s->voice, 0, vol, vol);
            break;
        }
    }

    trace_asc_write_reg(addr, size, value);
    s->regs[addr] = value;
}

static const MemoryRegionOps asc_regs_ops = {
    .read = asc_read,
    .write = asc_write,
    .endianness = DEVICE_BIG_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    }
};

static uint64_t asc_ext_read(void *opaque, hwaddr addr,
                             unsigned size)
{
    ASCFIFOState *fs = opaque;
    uint64_t value;

    value = fs->extregs[addr];

    trace_asc_read_extreg('A' + fs->index, addr, size, value);
    return value;
}

static void asc_ext_write(void *opaque, hwaddr addr, uint64_t value,
                          unsigned size)
{
    ASCFIFOState *fs = opaque;

    trace_asc_write_extreg('A' + fs->index, addr, size, value);

    fs->extregs[addr] = value;
}

static const MemoryRegionOps asc_extregs_ops = {
    .read = asc_ext_read,
    .write = asc_ext_write,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .endianness = DEVICE_BIG_ENDIAN,
};

static int asc_post_load(void *opaque, int version)
{
    ASCState *s = ASC(opaque);

    if (s->regs[ASC_MODE] != 0) {
        AUD_set_active_out(s->voice, 1);
    }

    return 0;
}

static const VMStateDescription vmstate_asc_fifo = {
    .name = "apple-sound-chip.fifo",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT8_ARRAY(fifo, ASCFIFOState, ASC_FIFO_SIZE),
        VMSTATE_UINT8(int_status, ASCFIFOState),
        VMSTATE_INT32(cnt, ASCFIFOState),
        VMSTATE_INT32(wptr, ASCFIFOState),
        VMSTATE_INT32(rptr, ASCFIFOState),
        VMSTATE_UINT8_ARRAY(extregs, ASCFIFOState, ASC_EXTREG_SIZE),
        VMSTATE_INT32(xa_cnt, ASCFIFOState),
        VMSTATE_UINT8(xa_val, ASCFIFOState),
        VMSTATE_UINT8(xa_flags, ASCFIFOState),
        VMSTATE_INT16_ARRAY(xa_last, ASCFIFOState, 2),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_asc = {
    .name = "apple-sound-chip",
    .version_id = 0,
    .minimum_version_id = 0,
    .post_load = asc_post_load,
    .fields = (const VMStateField[]) {
        VMSTATE_STRUCT_ARRAY(fifos, ASCState, 2, 0, vmstate_asc_fifo,
                             ASCFIFOState),
        VMSTATE_UINT8_ARRAY(regs, ASCState, ASC_REG_SIZE),
        VMSTATE_INT64(fifo_empty_ns, ASCState),
        VMSTATE_END_OF_LIST()
    }
};

static void asc_fifo_reset(ASCFIFOState *fs)
{
    fs->wptr = 0;
    fs->rptr = 0;
    fs->cnt = 0;
    fs->xa_cnt = -1;
    fs->int_status = 0;
}

static void asc_fifo_init(ASCFIFOState *fs, int index)
{
    ASCState *s = container_of(fs, ASCState, fifos[index]);
    char *name;

    fs->index = index;
    name = g_strdup_printf("asc.fifo%c", 'A' + index);
    memory_region_init_io(&fs->mem_fifo, OBJECT(s), &asc_fifo_ops, fs,
                          name, ASC_FIFO_SIZE);
    g_free(name);

    name = g_strdup_printf("asc.extregs%c", 'A' + index);
    memory_region_init_io(&fs->mem_extregs, OBJECT(s), &asc_extregs_ops,
                          fs, name, ASC_EXTREG_SIZE);
    g_free(name);
}

static void asc_reset_hold(Object *obj, ResetType type)
{
    ASCState *s = ASC(obj);

    AUD_set_active_out(s->voice, 0);

    memset(s->regs, 0, sizeof(s->regs));
    asc_fifo_reset(&s->fifos[0]);
    asc_fifo_reset(&s->fifos[1]);
    s->fifo_empty_ns = 0;

    if (s->type == ASC_TYPE_ASC) {
        /* FIFO half full IRQs enabled by default */
        s->fifos[0].extregs[ASC_EXTREGS_INTCTRL] = 1;
        s->fifos[1].extregs[ASC_EXTREGS_INTCTRL] = 1;
    }
}

static void asc_unrealize(DeviceState *dev)
{
    ASCState *s = ASC(dev);

    g_free(s->mixbuf);
    g_free(s->silentbuf);

    AUD_remove_card(&s->card);
}

static void asc_realize(DeviceState *dev, Error **errp)
{
    ASCState *s = ASC(dev);
    struct audsettings as;

    if (!AUD_register_card("Apple Sound Chip", &s->card, errp)) {
        return;
    }

    as.freq = ASC_FREQ;
    as.nchannels = 2;
    as.fmt = AUDIO_FORMAT_U8;
    as.endianness = AUDIO_HOST_ENDIANNESS;

    s->voice = AUD_open_out(&s->card, s->voice, "asc.out", s, asc_out_cb,
                            &as);
    s->shift = 1;
    s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift;
    s->mixbuf = g_malloc0(s->samples << s->shift);

    s->silentbuf = g_malloc0(s->samples << s->shift);
    memset(s->silentbuf, 0x80, s->samples << s->shift);

    /* Add easc registers if required */
    if (s->type == ASC_TYPE_EASC) {
        memory_region_add_subregion(&s->asc, ASC_EXTREG_OFFSET,
                                    &s->fifos[0].mem_extregs);
        memory_region_add_subregion(&s->asc,
                                    ASC_EXTREG_OFFSET + ASC_EXTREG_SIZE,
                                    &s->fifos[1].mem_extregs);
    }
}

static void asc_init(Object *obj)
{
    ASCState *s = ASC(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init(&s->asc, OBJECT(obj), "asc", ASC_SIZE);

    asc_fifo_init(&s->fifos[0], 0);
    asc_fifo_init(&s->fifos[1], 1);

    memory_region_add_subregion(&s->asc, ASC_FIFO_OFFSET,
                                &s->fifos[0].mem_fifo);
    memory_region_add_subregion(&s->asc,
                                ASC_FIFO_OFFSET + ASC_FIFO_SIZE,
                                &s->fifos[1].mem_fifo);

    memory_region_init_io(&s->mem_regs, OBJECT(obj), &asc_regs_ops, s,
                          "asc.regs", ASC_REG_SIZE);
    memory_region_add_subregion(&s->asc, ASC_REG_OFFSET, &s->mem_regs);

    sysbus_init_irq(sbd, &s->irq);
    sysbus_init_mmio(sbd, &s->asc);
}

static Property asc_properties[] = {
    DEFINE_AUDIO_PROPERTIES(ASCState, card),
    DEFINE_PROP_UINT8("asctype", ASCState, type, ASC_TYPE_ASC),
    DEFINE_PROP_END_OF_LIST(),
};

static void asc_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    ResettableClass *rc = RESETTABLE_CLASS(oc);

    dc->realize = asc_realize;
    dc->unrealize = asc_unrealize;
    set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
    dc->vmsd = &vmstate_asc;
    device_class_set_props(dc, asc_properties);
    rc->phases.hold = asc_reset_hold;
}

static const TypeInfo asc_info_types[] = {
    {
        .name = TYPE_ASC,
        .parent = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(ASCState),
        .instance_init = asc_init,
        .class_init = asc_class_init,
    },
};

DEFINE_TYPES(asc_info_types)
