Ejemplo n.º 1
0
        private byte device_start_es5503(ES5503Chip info, uint clock, byte flags)       //(const DEV_GEN_CFG* cfg, DEV_INFO* retDevInf)
        {
            ES5503Chip chip;

            chip = info;            //	 (ES5503Chip)calloc(1, sizeof(ES5503Chip));
            if (chip == null)
            {
                return(0xFF);
            }

            chip.irq_func  = null;
            chip.irq_param = null;
            chip.adc_func  = null;
            chip.adc_param = null;

            chip.dramsize        = 0x20000;                 // 128 KB
            chip.docram          = new byte[chip.dramsize]; // (byte*)malloc(chip.dramsize);
            chip.clock           = clock;                   // cfg.clock;
            chip.output_channels = flags;                   // cfg.flags;
            if (chip.output_channels == 0)
            {
                chip.output_channels = 1;
            }
            chip.outchn_mask = (byte)pow2_mask(chip.output_channels);

            chip.oscsenabled = 1;
            chip.output_rate = (uint)((chip.clock / 8) / (2 + chip.oscsenabled));              // (input clock / 8) / # of oscs. enabled + 2

            es5503_set_mute_mask(chip, 0x00000000);

            //chip._devData.chipInf = chip;
            //INIT_DEVINF(retDevInf, &chip._devData, chip.output_rate, &devDef);

            return(0x00);
        }
Ejemplo n.º 2
0
        private void device_stop_es5503(ES5503Chip info)
        {
            ES5503Chip chip = info;

            chip = null;
            //free(chip.docram);
            //free(chip);

            return;
        }
Ejemplo n.º 3
0
        private void es5503_set_mute_mask(ES5503Chip info, UInt32 MuteMask)
        {
            ES5503Chip chip = info;
            byte       CurChn;

            for (CurChn = 0; CurChn < 32; CurChn++)
            {
                chip.oscillators[CurChn].Muted = (byte)((MuteMask >> CurChn) & 0x01);
            }

            return;
        }
Ejemplo n.º 4
0
        // halt_osc: handle halting an oscillator
        // chip = chip ptr
        // onum = oscillator #
        // type = 1 for 0 found in sample data, 0 for hit end of table size
        private void es5503_halt_osc(ES5503Chip chip, int onum, int type, ref UInt32 accumulator, int resshift)
        {
            ES5503Osc pOsc        = chip.oscillators[onum];
            ES5503Osc pPartner    = chip.oscillators[onum ^ 1];
            int       mode        = (pOsc.control >> 1) & 3;
            int       partnerMode = (pPartner.control >> 1) & 3;

            // if 0 found in sample data or mode is not free-run, halt this oscillator
            if ((mode != (int)MODE.FREE) || (type != 0))
            {
                pOsc.control |= 1;
            }
            else                // preserve the relative phase of the oscillator when looping
            {
                UInt16 wtsize = (UInt16)(pOsc.wtsize - 1);
                UInt32 altram = accumulator >> resshift;

                if (altram > wtsize)
                {
                    altram -= wtsize;
                }
                else
                {
                    altram = 0;
                }

                accumulator = altram << resshift;
            }

            // if we're in swap mode or we're the even oscillator and the partner is in swap mode,
            // start the partner.
            if ((mode == (int)MODE.SWAP) || ((partnerMode == (int)MODE.SWAP) && ((onum & 1) == 0)))
            {
                pPartner.control    &= 0xff;             // ~1;    // clear the halt bit
                pPartner.accumulator = 0;                // and make sure it starts from the top (does this also need phase preservation?)
            }

            // IRQ enabled for this voice?
            if ((pOsc.control & 0x08) != 0)
            {
                pOsc.irqpend = 1;

                if (chip.irq_func != null)
                {
                    chip.irq_func(chip.irq_param, 1);
                }
            }
        }
Ejemplo n.º 5
0
        private void es5503_write_ram(ES5503Chip info, UInt32 offset, UInt32 length, byte[] data)
        {
            ES5503Chip chip = info;

            if (offset >= chip.dramsize)
            {
                return;
            }
            if (offset + length > chip.dramsize)
            {
                length = chip.dramsize - offset;
            }

            for (int i = 0; i < length; i++)
            {
                chip.docram[offset + i] = data[i];
            }

            return;
        }
Ejemplo n.º 6
0
        private void device_reset_es5503(ES5503Chip info)
        {
            ES5503Chip chip = info;
            int        osc;
            ES5503Osc  tempOsc;

            chip.rege0 = 0xff;

            for (osc = 0; osc < 32; osc++)
            {
                tempOsc                = chip.oscillators[osc];
                tempOsc.freq           = 0;
                tempOsc.wtsize         = 0;
                tempOsc.control        = 0;
                tempOsc.vol            = 0;
                tempOsc.data           = 0x80;
                tempOsc.wavetblpointer = 0;
                tempOsc.wavetblsize    = 0;
                tempOsc.resolution     = 0;
                tempOsc.accumulator    = 0;
                tempOsc.irqpend        = 0;
            }

            chip.oscsenabled = 1;

            chip.channel_strobe = 0;
            for (int i = 0; i < chip.dramsize; i++)
            {
                chip.docram[i] = 0x00;
            }

            chip.output_rate = (uint)((chip.clock / 8) / (2 + chip.oscsenabled));              // (input clock / 8) / # of oscs. enabled + 2
            //if (chip.SmpRateFunc != null)
            //chip.SmpRateFunc(chip.SmpRateData, chip.output_rate);

            return;
        }
Ejemplo n.º 7
0
        private void es5503_w(ES5503Chip info, byte offset, byte data)
        {
            ES5503Chip chip = info;

            if (offset < 0xe0)
            {
                int osc = offset & 0x1f;

                switch (offset & 0xe0)
                {
                case 0:                             // freq lo
                    chip.oscillators[osc].freq &= 0xff00;
                    chip.oscillators[osc].freq |= data;
                    break;

                case 0x20:                              // freq hi
                    chip.oscillators[osc].freq &= 0x00ff;
                    chip.oscillators[osc].freq |= (ushort)(data << 8);
                    break;

                case 0x40:                          // volume
                    chip.oscillators[osc].vol = data;
                    break;

                case 0x60:                          // data - ignore writes
                    break;

                case 0x80:                          // wavetable pointer
                    chip.oscillators[osc].wavetblpointer = (uint)(data << 8);
                    break;

                case 0xa0:                          // oscillator control
                    // if a fresh key-on, reset the accumulator
                    if ((chip.oscillators[osc].control & 1) != 0 && ((data & 1) == 0))
                    {
                        chip.oscillators[osc].accumulator = 0;
                    }
                    chip.oscillators[osc].control = data;
                    break;

                case 0xc0:                          // bank select / wavetable size / resolution
                    if ((data & 0x40) != 0)         // bank select - not used on the Apple IIgs
                    {
                        chip.oscillators[osc].wavetblpointer |= 0x10000;
                    }
                    else
                    {
                        chip.oscillators[osc].wavetblpointer &= 0xffff;
                    }

                    chip.oscillators[osc].wavetblsize = (byte)((data >> 3) & 7);
                    chip.oscillators[osc].wtsize      = wavesizes[chip.oscillators[osc].wavetblsize];
                    chip.oscillators[osc].resolution  = (byte)(data & 7);
                    break;
                }
            }
            else                 // global registers
            {
                switch (offset)
                {
                case 0xe0:                          // interrupt status
                    break;

                case 0xe1:                          // oscillator enable
                    chip.oscsenabled = (byte)(1 + ((data >> 1) & 0x1f));

                    chip.output_rate = (uint)((chip.clock / 8) / (2 + chip.oscsenabled));
                    //if (chip.SmpRateFunc != null)
                    //chip.SmpRateFunc(chip.SmpRateData, chip.output_rate);
                    break;

                case 0xe2:                          // A/D converter
                    break;
                }
            }
        }
Ejemplo n.º 8
0
        private byte es5503_r(ES5503Chip info, byte offset)
        {
            byte       retval;
            int        i;
            ES5503Chip chip = info;

            if (offset < 0xe0)
            {
                byte osc = (byte)(offset & 0x1f);

                switch (offset & 0xe0)
                {
                case 0:                             // freq lo
                    return((byte)(chip.oscillators[osc].freq & 0xff));

                case 0x20:                              // freq hi
                    return((byte)(chip.oscillators[osc].freq >> 8));

                case 0x40:                          // volume
                    return(chip.oscillators[osc].vol);

                case 0x60:                          // data
                    return(chip.oscillators[osc].data);

                case 0x80:                          // wavetable pointer
                    return((byte)((chip.oscillators[osc].wavetblpointer >> 8) & 0xff));

                case 0xa0:                          // oscillator control
                    return(chip.oscillators[osc].control);

                case 0xc0:                          // bank select / wavetable size / resolution
                    retval = 0;
                    if ((chip.oscillators[osc].wavetblpointer & 0x10000) != 0)
                    {
                        retval |= 0x40;
                    }

                    retval |= (byte)(chip.oscillators[osc].wavetblsize << 3);
                    retval |= chip.oscillators[osc].resolution;
                    return(retval);
                }
            }
            else                 // global registers
            {
                switch (offset)
                {
                case 0xe0:                          // interrupt status
                    retval = chip.rege0;

                    if (chip.irq_func != null)
                    {
                        chip.irq_func(chip.irq_param, 0);
                    }

                    // scan all oscillators
                    for (i = 0; i < chip.oscsenabled; i++)
                    {
                        if (chip.oscillators[i].irqpend != 0)
                        {
                            // signal this oscillator has an interrupt
                            retval = (byte)(i << 1);

                            chip.rege0 = (byte)(retval | 0x80);

                            // and clear its flag
                            chip.oscillators[i].irqpend = 0;
                            break;
                        }
                    }

                    // if any oscillators still need to be serviced, assert IRQ again immediately
                    for (i = 0; i < chip.oscsenabled; i++)
                    {
                        if (chip.oscillators[i].irqpend != 0)
                        {
                            if (chip.irq_func != null)
                            {
                                chip.irq_func(chip.irq_param, 1);
                            }
                            break;
                        }
                    }

                    return((byte)(retval | 0x41));

                case 0xe1:                          // oscillator enable
                    return((byte)((chip.oscsenabled - 1) << 1));

                case 0xe2:                          // A/D converter
                    if (chip.adc_func != null)
                    {
                        return(chip.adc_func(chip.adc_param, 0));
                    }
                    break;
                }
            }

            return(0);
        }
Ejemplo n.º 9
0
        private void es5503_pcm_update(ES5503Chip param, UInt32 samples, int[][] outputs)
        {
            byte       osc;
            UInt32     snum;
            UInt32     ramptr;
            ES5503Chip chip = param;
            byte       chnsStereo, chan;

            for (int i = 0; i < samples; i++)
            {
                outputs[0][i] = 0;
                outputs[1][i] = 0;
            }
            if (chip.docram == null)
            {
                return;
            }

            chnsStereo = (byte)(chip.output_channels & 0xff);            // ~1;
            for (osc = 0; osc < chip.oscsenabled; osc++)
            {
                ES5503Osc pOsc = chip.oscillators[osc];

                if ((pOsc.control & 1) == 0 && pOsc.Muted == 0)
                {
                    UInt32 wtptr = pOsc.wavetblpointer & wavemasks[pOsc.wavetblsize];
                    UInt32 altram;
                    UInt32 acc      = pOsc.accumulator;
                    UInt16 wtsize   = (UInt16)(pOsc.wtsize - 1);
                    UInt16 freq     = pOsc.freq;
                    Int16  vol      = pOsc.vol;
                    byte   chnMask  = (byte)((pOsc.control >> 4) & 0x0F);
                    int    resshift = resshifts[pOsc.resolution] - pOsc.wavetblsize;
                    UInt32 sizemask = accmasks[pOsc.wavetblsize];
                    Int32  outData;

                    chnMask &= chip.outchn_mask;
                    for (snum = 0; snum < samples; snum++)
                    {
                        altram = acc >> resshift;
                        ramptr = altram & sizemask;

                        acc += freq;

                        // channel strobe is always valid when reading; this allows potentially banking per voice
                        chip.channel_strobe = (byte)((pOsc.control >> 4) & 0xf);
                        pOsc.data           = chip.docram[ramptr + wtptr];

                        if (pOsc.data == 0x00)
                        {
                            es5503_halt_osc(chip, osc, 1, ref acc, resshift);
                        }
                        else
                        {
                            outData = (pOsc.data - 0x80) * vol;

                            // send groups of 2 channels to L or R
                            for (chan = 0; chan < chnsStereo; chan++)
                            {
                                if (chan == chnMask)
                                {
                                    outputs[chan & 1][snum] += outData;
                                }
                            }
                            outData = (outData * 181) >> 8;                             // outData *= sqrt(2)
                            // send remaining channels to L+R
                            for (; chan < chip.output_channels; chan++)
                            {
                                if (chan == chnMask)
                                {
                                    outputs[0][snum] += outData;
                                    outputs[1][snum] += outData;
                                }
                            }

                            if (altram >= wtsize)
                            {
                                es5503_halt_osc(chip, osc, 0, ref acc, resshift);
                            }
                        }

                        // if oscillator halted, we've got no more samples to generate
                        if ((pOsc.control & 1) != 0)
                        {
                            pOsc.control |= 1;
                            break;
                        }
                    }

                    pOsc.accumulator = acc;
                }
            }
        }