Пример #1
0
        public void c140_write_rom2(byte ChipID, uint ROMSize, uint DataStart, uint DataLength, byte[] ROMData, uint SrcStartAdr)
        {
            c140_state info = C140Data[ChipID];

            if (info.pRomSize != ROMSize)
            {
                info.pRom     = new byte[ROMSize];
                info.pRomSize = ROMSize;
                for (int i = 0; i < ROMSize; i++)
                {
                    info.pRom[i] = 0xff;
                }
                //memset(info->pRom, 0xFF, ROMSize);
            }
            if (DataStart > ROMSize)
            {
                return;
            }
            if (DataStart + DataLength > ROMSize)
            {
                DataLength = ROMSize - DataStart;
            }

            for (int i = 0; i < DataLength; i++)
            {
                info.pRom[i + DataStart] = ROMData[i + SrcStartAdr];
            }
            //memcpy((INT8*)info->pRom + DataStart, ROMData, DataLength);

            //System.Console.WriteLine("c140_write_rom2:{0}:{1}:{2}:{3}:{4}", ChipID, ROMSize, DataStart, DataLength, SrcStartAdr);
            return;
        }
Пример #2
0
        //void c140_set_base(device_t *device, void *base);

        public void c140_set_base(byte ChipID, byte[] Base)
        {
            //c140_state *info = get_safe_token(device);
            c140_state info = C140Data[ChipID];

            info.pRom = Base;
        }
Пример #3
0
        /*typedef struct _c140_interface c140_interface;
         * struct _c140_interface {
         *  int banking_type;
         * };*/

        public void c140_write_rom(byte ChipID, uint ROMSize, uint DataStart, uint DataLength, byte[] ROMData)
        {
            c140_state info = C140Data[ChipID];

            if (info.pRomSize != ROMSize)
            {
                info.pRom     = new byte[ROMSize];
                info.pRomSize = ROMSize;
                for (int i = 0; i < ROMSize; i++)
                {
                    info.pRom[i] = 0xff;
                }
                //memset(info->pRom, 0xFF, ROMSize);
            }
            if (DataStart > ROMSize)
            {
                return;
            }
            if (DataStart + DataLength > ROMSize)
            {
                DataLength = ROMSize - DataStart;
            }

            for (int i = 0; i < DataLength; i++)
            {
                info.pRom[i + DataStart] = ROMData[i];
            }
            //memcpy((INT8*)info->pRom + DataStart, ROMData, DataLength);

            return;
        }
Пример #4
0
        /*
         * find_sample: compute the actual address of a sample given it's
         * address and banking registers, as well as the board type.
         *
         * I suspect in "real life" this works like the Sega MultiPCM where the banking
         * is done by a small PAL or GAL external to the sound chip, which can be switched
         * per-game or at least per-PCB revision as addressing range needs grow.
         */

        private static long find_sample(c140_state info, long adrs, long bank, int voice)
        {
            //System.Console.Write("[{0:X}:{1:d}", adrs,bank);
            long newadr = 0;

            int[] asic219banks = new int[4] {
                0x1f7, 0x1f1, 0x1f3, 0x1f5
            };

            adrs = (bank << 16) + adrs;

            switch (info.banking_type)
            {
            case C140_TYPE.SYSTEM2:
                // System 2 banking
                newadr = ((adrs & 0x200000) >> 2) | (adrs & 0x7ffff);
                //System.Console.Write(":{0:X}]", newadr);
                break;

            case C140_TYPE.SYSTEM21:
                // System 21 banking.
                // similar to System 2's.
                newadr = ((adrs & 0x300000) >> 1) | (adrs & 0x7ffff);
                break;

            /*case C140_TYPE.SYSTEM21_A:
             *  // System 21 type A (simple) banking.
             *  // similar to System 2's.
             *  newadr = ((adrs & 0x300000) >> 1) + (adrs & 0x7ffff);
             *  break;
             *
             * case C140_TYPE.SYSTEM21_B:
             *  // System 21 type B (chip select) banking
             *
             *  // get base address of sample inside the bank
             *  newadr = ((adrs & 0x100000) >> 2) + (adrs & 0x3ffff);
             *
             *  // now add the starting bank offsets based on the 2
             *  // chip select bits.
             *  // 0x40000 picks individual 512k ROMs
             *  if ((adrs & 0x40000) != 0)
             *  {
             *      newadr += 0x80000;
             *  }
             *
             *  // and 0x200000 which group of chips...
             *  if ((adrs & 0x200000) != 0)
             *  {
             *      newadr += 0x100000;
             *  }
             *  break;*/

            case C140_TYPE.ASIC219:
                // ASIC219's banking is fairly simple
                newadr = (long)((info.REG[asic219banks[voice / 4]] & 0x3) * 0x20000) | adrs;
                break;
            }

            return(newadr);
        }
Пример #5
0
        /* C140.h */

        //#pragma once

        //public void c140_update(byte ChipID, int[][] outputs, int samples)
        //{

        //    //c140_state *info = (c140_state *)param;
        //    c140_state info = C140Data[ChipID];
        //    int i, j;

        //    int rvol, lvol;
        //    int dt;
        //    int sdt;
        //    int st, ed, sz;

        //    long pSampleData;
        //    int frequency, delta, offset, pos;
        //    int cnt, voicecnt;
        //    int lastdt, prevdt, dltdt;
        //    float pbase = (float)info.baserate * 2.0f / (float)info.sample_rate;
        //    //System.Console.Write("pbase={0:f6} info->baserate={1:d} info->sample_rate={2:d} \n", pbase, info.baserate, info.sample_rate);

        //    int[] lmix, rmix;

        //    if (samples > info.sample_rate) samples = info.sample_rate;

        //    /* zap the contents of the mixer buffer */
        //    for (int ind = 0; ind < samples; ind++)
        //    {
        //        info.mixer_buffer_left[ind] = 0;
        //        info.mixer_buffer_right[ind] = 0;
        //    }
        //    if (info.pRom == null)
        //        return;

        //    //System.Console.WriteLine("c140_update");

        //    /* get the number of voices to update */
        //    voicecnt = (info.banking_type == C140_TYPE.ASIC219) ? 16 : 24;

        //    //--- audio update
        //    for (i = 0; i < voicecnt; i++)
        //    {
        //        VOICE v = info.voi[i];
        //        //voice_registers vreg = (voice_registers)info.REG[i * 16];
        //        int vreg = i * 16;

        //        if (v.key != 0 && v.Muted == 0)
        //        {
        //            System.Console.Write("voicecnt={0:d} ", i);
        //            frequency = info.REG[vreg + 2] * 256 + info.REG[vreg + 3];

        //            /* Abort voice if no frequency value set */
        //            if (frequency == 0) continue;
        //            System.Console.Write("frequency={0:d} ", frequency);

        //            /* Delta =  frequency * ((8MHz/374)*2 / sample rate) */
        //            delta = (int)((float)frequency * pbase);
        //            System.Console.Write("delta={0:d} ", delta);

        //            /* Calculate left/right channel volumes */
        //            lvol = (info.REG[vreg + 1] * 32) / MAX_VOICE; //32ch -> 24ch
        //            rvol = (info.REG[vreg + 0] * 32) / MAX_VOICE;
        //            System.Console.Write("MAX_VOICE={0} lvol={1} vreg->volume_left={2} ", MAX_VOICE, lvol, info.REG[vreg + 1]);
        //            System.Console.Write("rvol={0} vreg->volume_right={1} ", rvol, info.REG[vreg + 0]);

        //            /* Set mixer outputs base pointers */
        //            lmix = info.mixer_buffer_left;
        //            rmix = info.mixer_buffer_right;

        //            /* Retrieve sample start/end and calculate size */
        //            st = (int)v.sample_start;
        //            ed = (int)v.sample_end;
        //            sz = ed - st;
        //            System.Console.Write("st={0} ed={1} ", st, ed);

        //            /* Retrieve base pointer to the sample data */
        //            //pSampleData=(signed char*)((FPTR)info->pRom + find_sample(info, st, v->bank, i));
        //            //pSampleData = info.pRom[find_sample(info, st, v.bank, i)];
        //            pSampleData = find_sample(info, st, v.bank, i);
        //            System.Console.Write("find_sample={0} ", find_sample(info, st, v.bank, i));

        //            /* Fetch back previous data pointers */
        //            offset = (int)v.ptoffset;
        //            pos = (int)v.pos;
        //            lastdt = (int)v.lastdt;
        //            prevdt = (int)v.prevdt;
        //            dltdt = (int)v.dltdt;
        //            System.Console.Write("offset={0} pos={1} lastdt={2} prevdt={3} dltdt={4} ", offset, pos, lastdt, prevdt, dltdt);

        //            System.Console.Write("v->mode={0} info->banking_type={1} ", v.mode, (int)info.banking_type);
        //            /* Switch on data type - compressed PCM is only for C140 */
        //            if ((v.mode & 8) != 0 && (info.banking_type != C140_TYPE.ASIC219))
        //            {
        //                //compressed PCM (maybe correct...)
        //                /* Loop for enough to fill sample buffer as requested */
        //                for (j = 0; j < samples; j++)
        //                {
        //                    offset += delta;
        //                    cnt = (offset >> 16) & 0x7fff;
        //                    offset &= 0xffff;
        //                    pos += cnt;
        //                    System.Console.Write("offset={0} cnt={1} pos={2} ", offset, cnt, pos);
        //                    //for(;cnt>0;cnt--)
        //                    {
        //                        /* Check for the end of the sample */
        //                        if (pos >= sz)
        //                        {
        //                            /* Check if its a looping sample, either stop or loop */
        //                            if ((v.mode & 0x10) != 0)
        //                            {
        //                                pos = (int)(v.sample_loop - st);
        //                            }
        //                            else
        //                            {
        //                                v.key = 0;
        //                                break;
        //                            }
        //                        }

        //                        /* Read the chosen sample byte */
        //                        dt = info.pRom[pSampleData + pos];
        //                        System.Console.Write("dt={0} ", dt);

        //                        /* decompress to 13bit range */        //2000.06.26 CAB
        //                        sdt = dt >> 3;              //signed
        //                        System.Console.Write("sdt={0} ", sdt);
        //                        if (sdt < 0) sdt = (sdt << (dt & 7)) - info.pcmtbl[dt & 7];
        //                        else sdt = (sdt << (dt & 7)) + info.pcmtbl[dt & 7];
        //                        System.Console.Write("sdt={0} info->pcmtbl[dt&7]={1} ", sdt, info.pcmtbl[dt & 7]);

        //                        prevdt = lastdt;
        //                        lastdt = sdt;
        //                        dltdt = (lastdt - prevdt);
        //                        System.Console.Write("prevdt={0} lastdt={1} dltdt={2} ", prevdt, lastdt, dltdt);
        //                    }

        //                    /* Caclulate the sample value */
        //                    dt = ((dltdt * offset) >> 16) + prevdt;
        //                    System.Console.Write("dt={0} ", dt);

        //                    /* Write the data to the sample buffers */
        //                    lmix[j] += (dt * lvol) >> (5 + 5);
        //                    rmix[j] += (dt * rvol) >> (5 + 5);
        //                    System.Console.Write("(dt*lvol)>>(5+5)={0} ", (dt * lvol) >> (5 + 5));
        //                    System.Console.Write("(dt*rvol)>>(5+5)={0} ", (dt * rvol) >> (5 + 5));
        //                }
        //            }
        //            else
        //            {
        //                /* linear 8bit signed PCM */
        //                for (j = 0; j < samples; j++)
        //                {
        //                    offset += delta;
        //                    cnt = (offset >> 16) & 0x7fff;
        //                    offset &= 0xffff;
        //                    pos += cnt;
        //                    System.Console.Write("linear offset={0} cnt={1} pos={2} ", offset, cnt, pos);
        //                    /* Check for the end of the sample */
        //                    if (pos >= sz)
        //                    {
        //                        /* Check if its a looping sample, either stop or loop */
        //                        if ((v.mode & 0x10) != 0)
        //                        {
        //                            pos = (int)(v.sample_loop - st);
        //                        }
        //                        else
        //                        {
        //                            v.key = 0;
        //                            break;
        //                        }
        //                    }

        //                    if (cnt != 0)
        //                    {
        //                        prevdt = lastdt;

        //                        if (info.banking_type == C140_TYPE.ASIC219)
        //                        {
        //                            //lastdt = pSampleData[BYTE_XOR_BE(pos)];
        //                            lastdt = info.pRom[pSampleData + (pos ^ 0x01)];

        //                            // Sign + magnitude format
        //                            if ((v.mode & 0x01) != 0 && ((lastdt & 0x80) != 0))
        //                                lastdt = -(lastdt & 0x7f);

        //                            // Sign flip
        //                            if ((v.mode & 0x40) != 0)
        //                                lastdt = -lastdt;
        //                        }
        //                        else
        //                        {
        //                            lastdt = ((info.pRom[pSampleData + pos] & 0x80) != 0) ? (info.pRom[pSampleData + pos] - 256) : info.pRom[pSampleData + pos];
        //                        }

        //                        dltdt = (lastdt - prevdt);
        //                        System.Console.Write("prevdt={0} lastdt={1} dltdt={2} ", prevdt, lastdt, dltdt);
        //                    }

        //                    /* Caclulate the sample value */
        //                    dt = ((dltdt * offset) >> 16) + prevdt;
        //                    System.Console.Write("dt={0} ", dt);

        //                    /* Write the data to the sample buffers */
        //                    lmix[j] += (dt * lvol) >> 5;
        //                    rmix[j] += (dt * rvol) >> 5;
        //                    System.Console.Write("(dt*lvol)>>5={0} ", (dt * lvol) >> 5);
        //                    System.Console.Write("(dt*rvol)>>5={0} ", (dt * rvol) >> 5);
        //                }
        //            }

        //            /* Save positional data for next callback */
        //            v.ptoffset = offset;
        //            v.pos = pos;
        //            v.lastdt = lastdt;
        //            v.prevdt = prevdt;
        //            v.dltdt = dltdt;
        //            System.Console.Write("\n");
        //        }
        //    }

        //    /* render to MAME's stream buffer */
        //    lmix = info.mixer_buffer_left;
        //    rmix = info.mixer_buffer_right;
        //    {
        //        int[] dest1 = outputs[0];
        //        int[] dest2 = outputs[1];
        //        for (i = 0; i < samples; i++)
        //        {
        //            //*dest1++ = limit(8*(*lmix++));
        //            //*dest2++ = limit(8*(*rmix++));
        //            dest1[i] = 8 * lmix[i];
        //            dest2[i] = 8 * rmix[i];
        //        }
        //    }
        //}

        //READ8_DEVICE_HANDLER( c140_r );
        //WRITE8_DEVICE_HANDLER( c140_w );

        public byte c140_r(byte ChipID, uint offset)
        {
            //c140_state *info = get_safe_token(device);
            c140_state info = C140Data[ChipID];

            offset &= 0x1ff;
            return(info.REG[offset]);
        }
Пример #6
0
        public override void Stop(byte ChipID)
        {
            c140_state info = C140Data[ChipID];

            //free(info->pRom);
            info.pRom = null;
            //free(info->mixer_buffer_left);
            info.mixer_buffer_left  = null;
            info.mixer_buffer_right = null;

            //return;
        }
Пример #7
0
        public void c140_set_mute_mask(byte ChipID, uint MuteMask)
        {
            c140_state info = C140Data[ChipID];
            byte       CurChn;

            for (CurChn = 0; CurChn < MAX_VOICE; CurChn++)
            {
                info.voi[CurChn].Muted = (byte)((MuteMask >> CurChn) & 0x01);
            }

            return;
        }
Пример #8
0
        private static long find_sample(c140_state info, long adrs, long bank, int voice)
        {
            adrs = (bank << 16) + adrs;

            switch (info.banking_type)
            {
            case C140_TYPE.SYSTEM2:
                // System 2 banking
                return(((adrs & 0x200000) >> 2) | (adrs & 0x7ffff));

            case C140_TYPE.SYSTEM21:
                // System 21 banking.
                // similar to System 2's.
                return(((adrs & 0x300000) >> 1) | (adrs & 0x7ffff));

            case C140_TYPE.ASIC219:
                // ASIC219's banking is fairly simple
                return((long)((info.REG[asic219banks[voice / 4]] & 0x3) * 0x20000) | adrs);
            }

            return(0);
        }
Пример #9
0
        //private int debugCnt = 0;

        public override void Update(byte ChipID, int[][] outputs, int samples)
        {
            //c140_state *info = (c140_state *)param;
            c140_state info = C140Data[ChipID];
            int        i, j;

            int rvol, lvol;
            int dt;
            int sdt;
            int st, ed, sz;

            long  pSampleData;
            int   frequency, delta, offset, pos;
            int   cnt, voicecnt;
            int   lastdt, prevdt, dltdt;
            float pbase = (float)info.baserate * 2.0f / (float)info.sample_rate;

            int[] lmix, rmix;

            if (samples > info.sample_rate)
            {
                samples = info.sample_rate;
            }

            /* zap the contents of the mixer buffer */
            for (int ind = 0; ind < samples; ind++)
            {
                info.mixer_buffer_left[ind]  = 0;
                info.mixer_buffer_right[ind] = 0;
            }
            if (info.pRom == null)
            {
                return;
            }

            /* get the number of voices to update */
            voicecnt = (info.banking_type == C140_TYPE.ASIC219) ? 16 : 24;

            //--- audio update
            for (i = 0; i < voicecnt; i++)
            {
                VOICE v = info.voi[i];
                //voice_registers vreg = (voice_registers)info.REG[i * 16];
                int vreg = i * 16;

                if (v.key == 0 || v.Muted != 0)
                {
                    continue;
                }
                frequency = (info.REG[vreg + 2] << 8) | info.REG[vreg + 3];

                /* Abort voice if no frequency value set */
                if (frequency == 0)
                {
                    continue;
                }

                /* Delta =  frequency * ((8MHz/374)*2 / sample rate) */
                delta = (int)(frequency * pbase);

                /* Calculate left/right channel volumes */
                lvol = (info.REG[vreg + 1] << 5) / MAX_VOICE; //32ch -> 24ch
                rvol = (info.REG[vreg + 0] << 5) / MAX_VOICE;

                /* Set mixer outputs base pointers */
                lmix = info.mixer_buffer_left;
                rmix = info.mixer_buffer_right;

                /* Retrieve sample start/end and calculate size */
                st = (int)v.sample_start;
                ed = (int)v.sample_end;
                sz = ed - st;

                /* Retrieve base pointer to the sample data */
                //pSampleData=(signed char*)((FPTR)info->pRom + find_sample(info, st, v->bank, i));
                //pSampleData = info.pRom[find_sample(info, st, v.bank, i)];
                pSampleData = find_sample(info, st, v.bank, i);

                /* Fetch back previous data pointers */
                offset = (int)v.ptoffset;
                pos    = (int)v.pos;
                lastdt = (int)v.lastdt;
                prevdt = (int)v.prevdt;
                dltdt  = (int)v.dltdt;

                /* Switch on data type - compressed PCM is only for C140 */
                if ((v.mode & 8) != 0 && (info.banking_type != C140_TYPE.ASIC219))
                {
                    //compressed PCM (maybe correct...)
                    /* Loop for enough to fill sample buffer as requested */
                    for (j = 0; j < samples; j++)
                    {
                        offset += delta;
                        cnt     = (offset >> 16) & 0x7fff;
                        offset &= 0xffff;
                        pos    += cnt;
                        /* Check for the end of the sample */
                        if (pos >= sz)
                        {
                            //Console.WriteLine("c140 pos[{0:x}]",pos);
                            //debugCnt = 20;
                            /* Check if its a looping sample, either stop or loop */
                            if ((v.mode & 0x10) != 0)
                            {
                                pos = (int)(v.sample_loop - st);
                            }
                            else
                            {
                                v.key = 0;
                                break;
                            }
                        }

                        /* Read the chosen sample byte */
                        dt = (sbyte)info.pRom[pSampleData + pos];

                        /* decompress to 13bit range */ //2000.06.26 CAB
                        sdt = dt >> 3;                  //signed
                        if (sdt < 0)
                        {
                            sdt = (sdt << (dt & 7)) - info.pcmtbl[dt & 7];
                        }
                        else
                        {
                            sdt = (sdt << (dt & 7)) + info.pcmtbl[dt & 7];
                        }

                        prevdt = lastdt;
                        lastdt = sdt;
                        dltdt  = (lastdt - prevdt);

                        /* Caclulate the sample value */
                        dt = ((dltdt * offset) >> 16) + prevdt;

                        /* Write the data to the sample buffers */
                        lmix[j] += (dt * lvol) >> (5 + 5);
                        rmix[j] += (dt * rvol) >> (5 + 5);
                    }
                }
                else
                {
                    /* linear 8bit signed PCM */
                    for (j = 0; j < samples; j++)
                    {
                        offset += delta;
                        cnt     = (offset >> 16) & 0x7fff;
                        offset &= 0xffff;
                        pos    += cnt;
                        /* Check for the end of the sample */
                        if (pos >= sz)
                        {
                            //Console.WriteLine("c140 pos[{0:x}]", pos);
                            //debugCnt = 20;
                            /* Check if its a looping sample, either stop or loop */
                            if ((v.mode & 0x10) != 0)
                            {
                                pos = (int)(v.sample_loop - st);
                            }
                            else
                            {
                                v.key = 0;
                                break;
                            }
                        }

                        if (cnt != 0)
                        {
                            prevdt = lastdt;

                            if (info.banking_type == C140_TYPE.ASIC219)
                            {
                                lastdt = (sbyte)info.pRom[pSampleData + (pos ^ 0x01)];

                                // Sign + magnitude format
                                if ((v.mode & 0x01) != 0 && ((lastdt & 0x80) != 0))
                                {
                                    lastdt = -(lastdt & 0x7f);
                                }
                                // Sign flip
                                if ((v.mode & 0x40) != 0)
                                {
                                    lastdt = -lastdt;
                                }
                            }
                            else
                            {
                                lastdt = (sbyte)info.pRom[pSampleData + pos];
                            }

                            dltdt = (lastdt - prevdt);
                        }

                        /* Caclulate the sample value */
                        dt = ((dltdt * offset) >> 16) + prevdt;

                        /* Write the data to the sample buffers */
                        lmix[j] += (dt * lvol) >> 5;
                        rmix[j] += (dt * rvol) >> 5;
                    }
                }

                /* Save positional data for next callback */
                v.ptoffset = offset;
                v.pos      = pos;
                v.lastdt   = lastdt;
                v.prevdt   = prevdt;
                v.dltdt    = dltdt;
            }

            /* render to MAME's stream buffer */
            lmix = info.mixer_buffer_left;
            rmix = info.mixer_buffer_right;
            {
                int[] dest1 = outputs[0];
                int[] dest2 = outputs[1];
                for (i = 0; i < samples; i++)
                {
                    dest1[i] = lmix[i] << 3;
                    dest2[i] = rmix[i] << 3;
                    //if (debugCnt > 0)
                    //{
                    //    debugCnt--;
                    //    Console.WriteLine("{0:x}  {0:d}", lmix[i]);
                    //}
                }
            }

            visVolume[ChipID][0][0] = outputs[0][0];
            visVolume[ChipID][0][1] = outputs[1][0];
        }
Пример #10
0
        private void c140_w(byte ChipID, uint offset, byte data)
        {
            //c140_state *info = get_safe_token(device);
            c140_state info = C140Data[ChipID];

            //info->stream->update();

            offset &= 0x1ff;

            // mirror the bank registers on the 219, fixes bkrtmaq (and probably xday2 based on notes in the HLE)
            if ((offset >= 0x1f8) && (info.banking_type == C140_TYPE.ASIC219))
            {
                offset -= 8;
            }

            info.REG[offset] = data;
            if (offset < 0x180)
            {
                VOICE v = info.voi[offset >> 4];

                if ((offset & 0xf) == 0x5)
                {
                    if ((data & 0x80) != 0)
                    {
                        //voice_registers vreg = (voice_registers)info.REG[offset & 0x1f0];
                        int vreg = (int)(offset & 0x1f0);
                        v.key      = 1;
                        v.ptoffset = 0;
                        v.pos      = 0;
                        v.lastdt   = 0;
                        v.prevdt   = 0;
                        v.dltdt    = 0;
                        v.bank     = info.REG[vreg + 4];// vreg.bank;
                        v.mode     = data;

                        // on the 219 asic, addresses are in words
                        if (info.banking_type == C140_TYPE.ASIC219)
                        {
                            v.sample_loop  = ((info.REG[vreg + 10] * 256) | info.REG[vreg + 11]) * 2;
                            v.sample_start = ((info.REG[vreg + 6] * 256) | info.REG[vreg + 7]) * 2;
                            v.sample_end   = ((info.REG[vreg + 8] * 256) | info.REG[vreg + 9]) * 2;

                            //#if 0
                            //logerror("219: play v %d mode %02x start %x loop %x end %x\n",
                            //	offset>>4, v->mode,
                            //	find_sample(info, v->sample_start, v->bank, offset>>4),
                            //	find_sample(info, v->sample_loop, v->bank, offset>>4),
                            //	find_sample(info, v->sample_end, v->bank, offset>>4));
                            //#endif
                        }
                        else
                        {
                            v.sample_loop  = (info.REG[vreg + 10] << 8) | info.REG[vreg + 11];
                            v.sample_start = (info.REG[vreg + 6] << 8) | info.REG[vreg + 7];
                            v.sample_end   = (info.REG[vreg + 8] << 8) | info.REG[vreg + 9];
                        }
                    }
                    else
                    {
                        v.key = 0;
                    }
                }
            }
        }
Пример #11
0
        public override void Update(byte ChipID, int[][] outputs, int samples)
        {
            //c140_state *info = (c140_state *)param;
            c140_state info = C140Data[ChipID];
            int        i, j;

            int rvol, lvol;
            int dt;
            int sdt;
            int st, ed, sz;

            long  pSampleData;
            int   frequency, delta, offset, pos;
            int   cnt, voicecnt;
            int   lastdt, prevdt, dltdt;
            float pbase = (float)info.baserate * 2.0f / (float)info.sample_rate;

            //System.Console.Write("pbase={0:f6} info->baserate={1:d} info->sample_rate={2:d} \n", pbase, info.baserate, info.sample_rate);

            int[] lmix, rmix;

            if (samples > info.sample_rate)
            {
                samples = info.sample_rate;
            }

            /* zap the contents of the mixer buffer */
            for (int ind = 0; ind < samples; ind++)
            {
                info.mixer_buffer_left[ind]  = 0;
                info.mixer_buffer_right[ind] = 0;
            }
            if (info.pRom == null)
            {
                return;
            }

            //System.Console.WriteLine("c140_update");

            /* get the number of voices to update */
            voicecnt = (info.banking_type == C140_TYPE.ASIC219) ? 16 : 24;

            //--- audio update
            for (i = 0; i < voicecnt; i++)
            {
                VOICE v = info.voi[i];
                //voice_registers vreg = (voice_registers)info.REG[i * 16];
                int vreg = i * 16;

                if (v.key != 0 && v.Muted == 0)
                {
                    //System.Console.Write("voicecnt={0:d} ", i);
                    frequency = info.REG[vreg + 2] * 256 + info.REG[vreg + 3];

                    /* Abort voice if no frequency value set */
                    if (frequency == 0)
                    {
                        continue;
                    }
                    //System.Console.Write("frequency={0:d} ", frequency);

                    /* Delta =  frequency * ((8MHz/374)*2 / sample rate) */
                    delta = (int)((float)frequency * pbase);
                    //System.Console.Write("delta={0:d} ", delta);

                    /* Calculate left/right channel volumes */
                    lvol = (info.REG[vreg + 1] * 32) / MAX_VOICE; //32ch -> 24ch
                    rvol = (info.REG[vreg + 0] * 32) / MAX_VOICE;
                    //System.Console.Write("MAX_VOICE={0} lvol={1} vreg->volume_left={2} ", MAX_VOICE, lvol, info.REG[vreg + 1]);
                    //System.Console.Write("rvol={0} vreg->volume_right={1} ", rvol, info.REG[vreg + 0]);

                    /* Set mixer outputs base pointers */
                    lmix = info.mixer_buffer_left;
                    rmix = info.mixer_buffer_right;

                    /* Retrieve sample start/end and calculate size */
                    st = (int)v.sample_start;
                    ed = (int)v.sample_end;
                    sz = ed - st;
                    //System.Console.Write("st={0} ed={1} ", st, ed);

                    /* Retrieve base pointer to the sample data */
                    //pSampleData=(signed char*)((FPTR)info->pRom + find_sample(info, st, v->bank, i));
                    //pSampleData = info.pRom[find_sample(info, st, v.bank, i)];
                    pSampleData = find_sample(info, st, v.bank, i);
                    //System.Console.Write("find_sample={0} ", find_sample(info, st, v.bank, i));

                    /* Fetch back previous data pointers */
                    offset = (int)v.ptoffset;
                    pos    = (int)v.pos;
                    lastdt = (int)v.lastdt;
                    prevdt = (int)v.prevdt;
                    dltdt  = (int)v.dltdt;
                    //System.Console.Write("offset={0} pos={1} lastdt={2} prevdt={3} dltdt={4} ", offset, pos, lastdt, prevdt, dltdt);

                    //System.Console.Write("v->mode={0} info->banking_type={1} ", v.mode, (int)info.banking_type);
                    /* Switch on data type - compressed PCM is only for C140 */
                    if ((v.mode & 8) != 0 && (info.banking_type != C140_TYPE.ASIC219))
                    {
                        //compressed PCM (maybe correct...)
                        /* Loop for enough to fill sample buffer as requested */
                        for (j = 0; j < samples; j++)
                        {
                            offset += delta;
                            cnt     = (offset >> 16) & 0x7fff;
                            offset &= 0xffff;
                            pos    += cnt;
                            //System.Console.Write("offset={0} cnt={1} pos={2} ", offset, cnt, pos);
                            //for(;cnt>0;cnt--)
                            {
                                /* Check for the end of the sample */
                                if (pos >= sz)
                                {
                                    /* Check if its a looping sample, either stop or loop */
                                    if ((v.mode & 0x10) != 0)
                                    {
                                        pos = (int)(v.sample_loop - st);
                                    }
                                    else
                                    {
                                        v.key = 0;
                                        break;
                                    }
                                }

                                /* Read the chosen sample byte */
                                //dt = info.pRom[pSampleData + pos];
                                dt = ((info.pRom[pSampleData + pos] & 0x80) != 0) ? (info.pRom[pSampleData + pos] - 256) : info.pRom[pSampleData + pos];
                                //System.Console.Write("dt={0} ", dt);

                                /* decompress to 13bit range */ //2000.06.26 CAB
                                sdt = dt >> 3;                  //signed
                                //System.Console.Write("sdt={0} ", sdt);
                                if (sdt < 0)
                                {
                                    sdt = (sdt << (dt & 7)) - info.pcmtbl[dt & 7];
                                }
                                else
                                {
                                    sdt = (sdt << (dt & 7)) + info.pcmtbl[dt & 7];
                                }
                                //System.Console.Write("sdt={0} info->pcmtbl[dt&7]={1} ", sdt, info.pcmtbl[dt & 7]);

                                prevdt = lastdt;
                                lastdt = sdt;
                                dltdt  = (lastdt - prevdt);
                                //System.Console.Write("prevdt={0} lastdt={1} dltdt={2} ", prevdt, lastdt, dltdt);
                            }

                            /* Caclulate the sample value */
                            dt = ((dltdt * offset) >> 16) + prevdt;
                            //System.Console.Write("dt={0} ", dt);

                            /* Write the data to the sample buffers */
                            lmix[j] += (dt * lvol) >> (5 + 5);
                            rmix[j] += (dt * rvol) >> (5 + 5);
                            //System.Console.Write("(dt*lvol)>>(5+5)={0} ", (dt * lvol) >> (5 + 5));
                            //System.Console.Write("(dt*rvol)>>(5+5)={0} ", (dt * rvol) >> (5 + 5));
                        }
                    }
                    else
                    {
                        /* linear 8bit signed PCM */
                        for (j = 0; j < samples; j++)
                        {
                            offset += delta;
                            cnt     = (offset >> 16) & 0x7fff;
                            offset &= 0xffff;
                            pos    += cnt;
                            //System.Console.Write("linear offset={0} cnt={1} pos={2} ", offset, cnt, pos);
                            /* Check for the end of the sample */
                            if (pos >= sz)
                            {
                                /* Check if its a looping sample, either stop or loop */
                                if ((v.mode & 0x10) != 0)
                                {
                                    pos = (int)(v.sample_loop - st);
                                }
                                else
                                {
                                    v.key = 0;
                                    break;
                                }
                            }

                            if (cnt != 0)
                            {
                                prevdt = lastdt;

                                if (info.banking_type == C140_TYPE.ASIC219)
                                {
                                    //lastdt = pSampleData[BYTE_XOR_BE(pos)];
                                    lastdt = (sbyte)info.pRom[pSampleData + (pos ^ 0x01)];
                                    //System.Console.WriteLine("pos:{0} lastdt:{1}", pos, lastdt);

                                    // Sign + magnitude format
                                    if ((v.mode & 0x01) != 0 && ((lastdt & 0x80) != 0))
                                    {
                                        lastdt = -(lastdt & 0x7f);
                                        //lastdt *= -1;
                                    }
                                    // Sign flip
                                    if ((v.mode & 0x40) != 0)
                                    {
                                        lastdt = -lastdt;
                                    }

                                    //lastdt >>= 2;
                                }
                                else
                                {
                                    lastdt = ((info.pRom[pSampleData + pos] & 0x80) != 0) ? (info.pRom[pSampleData + pos] - 256) : info.pRom[pSampleData + pos];
                                }

                                dltdt = (lastdt - prevdt);
                                //System.Console.Write("prevdt={0} lastdt={1} dltdt={2} ", prevdt, lastdt, dltdt);
                            }

                            /* Caclulate the sample value */
                            dt = ((dltdt * offset) >> 16) + prevdt;
                            //System.Console.Write("dt={0} ", dt);

                            /* Write the data to the sample buffers */
                            lmix[j] += (dt * lvol) >> 5;
                            rmix[j] += (dt * rvol) >> 5;
                            //System.Console.Write("(dt*lvol)>>5={0} ", (dt * lvol) >> 5);
                            //System.Console.Write("(dt*rvol)>>5={0} ", (dt * rvol) >> 5);
                        }
                    }

                    /* Save positional data for next callback */
                    v.ptoffset = offset;
                    v.pos      = pos;
                    v.lastdt   = lastdt;
                    v.prevdt   = prevdt;
                    v.dltdt    = dltdt;
                    //System.Console.Write("\n");
                }
            }

            /* render to MAME's stream buffer */
            lmix = info.mixer_buffer_left;
            rmix = info.mixer_buffer_right;
            {
                int[] dest1 = outputs[0];
                int[] dest2 = outputs[1];
                for (i = 0; i < samples; i++)
                {
                    //*dest1++ = limit(8*(*lmix++));
                    //*dest2++ = limit(8*(*rmix++));
                    dest1[i] = 8 * lmix[i];
                    dest2[i] = 8 * rmix[i];
                }
            }

            visVolume[ChipID][0][0] = outputs[0][0];
            visVolume[ChipID][0][1] = outputs[1][0];
        }