Exemple #1
0
        /************************************************/
        /*    RF5C68 write register                     */
        /************************************************/

        //WRITE8_DEVICE_HANDLER( rf5c68_w )
        public void rf5c68_w(byte ChipID, int offset, byte data)
        {
            //rf5c68_state *chip = get_safe_token(device);
            rf5c68_state chip = RF5C68Data[ChipID];
            pcm_channel  chan = chip.chan[chip.cbank];
            int          i;

            /* force the stream to update first */
            //stream_update(chip.stream);

            /* switch off the address */
            switch (offset)
            {
            case 0x00:      /* envelope */
                chan.env = data;
                break;

            case 0x01:      /* pan */
                chan.pan = data;
                break;

            case 0x02:      /* FDL */
                chan.step = (UInt16)((chan.step & 0xff00) | (data & 0x00ff));
                break;

            case 0x03:      /* FDH */
                chan.step = (UInt16)((chan.step & 0x00ff) | ((data << 8) & 0xff00));
                break;

            case 0x04:      /* LSL */
                chan.loopst = (UInt16)((chan.loopst & 0xff00) | (data & 0x00ff));
                break;

            case 0x05:      /* LSH */
                chan.loopst = (UInt16)((chan.loopst & 0x00ff) | ((data << 8) & 0xff00));
                break;

            case 0x06:      /* ST */
                chan.start = data;
                if (chan.enable == 0)
                {
                    chan.addr = (uint)(chan.start << (8 + 11));
                }
                break;

            case 0x07:      /* control reg */
                chip.enable = (byte)((data >> 7) & 1);
                if ((data & 0x40) != 0)
                {
                    chip.cbank = (byte)(data & 7);
                }
                else
                {
                    chip.wbank = (byte)(data & 15);
                }
                break;

            case 0x08:      /* channel on/off reg */
                for (i = 0; i < 8; i++)
                {
                    byte old = chip.chan[i].enable;

                    chip.chan[i].enable = (byte)((~data >> i) & 1);

                    if (old == 0 && chip.chan[i].enable != 0)
                    {
                        chip.chan[i].keyOn = true;
                    }

                    if (chip.chan[i].enable == 0)
                    {
                        chip.chan[i].addr = (uint)(chip.chan[i].start << (8 + 11));
                    }
                }
                break;
            }
        }
Exemple #2
0
        //static STREAM_UPDATE( rf5c68_update )
        private void rf5c68_update(byte ChipID, int[][] outputs, int samples)
        {
            //rf5c68_state *chip = (rf5c68_state *)param;
            rf5c68_state chip = RF5C68Data[ChipID];
            mem_stream   ms   = chip.memstrm;

            int[] left = outputs[0];
            int[] right = outputs[1];
            int   i, j;

            /* start with clean buffers */
            for (int ind = 0; ind < samples; ind++)
            {
                left[ind]  = 0;
                right[ind] = 0;
            }

            /* bail if not enabled */
            if (chip.enable == 0)
            {
                return;
            }

            /* loop over channels */
            for (i = 0; i < NUM_CHANNELS; i++)
            {
                pcm_channel chan = chip.chan[i];

                /* if this channel is active, accumulate samples */
                if (chan.enable != 0)// && chan.Muted == 0)
                {
                    int lv = (chan.pan & 0x0f) * chan.env;
                    int rv = ((chan.pan >> 4) & 0x0f) * chan.env;

                    /* loop over the sample buffer */
                    for (j = 0; j < samples; j++)
                    {
                        int sample;

                        /* trigger sample callback */

                        /*if(chip.sample_callback)
                         * {
                         *  if(((chan.addr >> 11) & 0xfff) == 0xfff)
                         *      chip.sample_callback(chip.device,((chan.addr >> 11)/0x2000));
                         * }*/

                        memstream_sample_check(chip, (chan.addr >> 11) & 0xFFFF, chan.step);
                        /* fetch the sample and handle looping */
                        sample = chip.data[(chan.addr >> 11) & 0xffff];
                        if (sample == 0xff)
                        {
                            chan.addr = (uint)(chan.loopst << 11);
                            sample    = chip.data[(chan.addr >> 11) & 0xffff];

                            /* if we loop to a loop point, we're effectively dead */
                            if (sample == 0xff)
                            {
                                chan.key = false;
                                break;
                            }
                        }
                        chan.key   = true;
                        chan.addr += chan.step;

                        if (chan.Muted == 0)
                        {
                            /* add to the buffer */
                            if ((sample & 0x80) != 0)
                            {
                                sample   &= 0x7f;
                                left[j]  += (sample * lv) >> 5;
                                right[j] += (sample * rv) >> 5;
                            }
                            else
                            {
                                left[j]  -= (sample * lv) >> 5;
                                right[j] -= (sample * rv) >> 5;
                            }
                        }

                        //Console.WriteLine("Ch:{0} L:{1} R:{2}", i, outputs[0][j], outputs[1][j]);
                    }
                }
            }

            if (samples != 0 && ms.CurAddr < ms.EndAddr)
            {
                ms.CurStep += (UInt16)(STEAM_STEP * samples);
                if (ms.CurStep >= 0x0800)  // 1 << 11
                {
                    i           = ms.CurStep >> 11;
                    ms.CurStep &= 0x07FF;

                    if (ms.CurAddr + i > ms.EndAddr)
                    {
                        i = (int)(ms.EndAddr - ms.CurAddr);
                    }

                    //memcpy(chip.data + ms.CurAddr, ms.MemPnt + (ms.CurAddr - ms.BaseAddr), i);
                    Array.Copy(ms.MemPnt, (ms.CurAddr - ms.BaseAddr), chip.data, ms.CurAddr, i);
                    ms.CurAddr += (uint)i;
                }
            }
            // I think, this is completely useless
            /* now clamp and shift the result (output is only 10 bits) */

            /*for (j = 0; j < samples; j++)
             * {
             *  stream_sample_t temp;
             *
             *  temp = left[j];
             *  if (temp > 32767) temp = 32767;
             *  else if (temp < -32768) temp = -32768;
             *  left[j] = temp & ~0x3f;
             *
             *  temp = right[j];
             *  if (temp > 32767) temp = 32767;
             *  else if (temp < -32768) temp = -32768;
             *  right[j] = temp & ~0x3f;
             * }*/
        }