Beispiel #1
0
        private void rf5c68_mem_stream_flush(rf5c68_state chip)
        {
            mem_stream ms = chip.memstrm;

            if (ms.CurAddr >= ms.EndAddr)
            {
                return;
            }

            //memcpy(chip.data + ms.CurAddr, ms.MemPnt + (ms.CurAddr - ms.BaseAddr), ms.EndAddr - ms.CurAddr);
            Array.Copy(ms.MemPnt, (ms.CurAddr - ms.BaseAddr), chip.data, ms.CurAddr, ms.EndAddr - ms.CurAddr);
            ms.CurAddr = ms.EndAddr;

            return;
        }
Beispiel #2
0
        public void rf5c68_write_ram2(byte ChipID, int DataStart, int DataLength, byte[] RAMData, uint SrcStartAdr)
        {
            rf5c68_state chip = RF5C68Data[ChipID];
            mem_stream   ms   = chip.memstrm;
            UInt16       BytCnt;

            DataStart |= chip.wbank * 0x1000;
            if (DataStart >= chip.datasize)
            {
                return;
            }
            if (DataStart + DataLength > chip.datasize)
            {
                DataLength = (int)(chip.datasize - DataStart);
            }

            //memcpy(chip.data + DataStart, RAMData, DataLength);

            rf5c68_mem_stream_flush(chip);

            ms.BaseAddr = (uint)DataStart;
            ms.CurAddr  = ms.BaseAddr;
            ms.EndAddr  = (uint)(ms.BaseAddr + DataLength);
            ms.CurStep  = 0x0000;
            byte[] dat = new byte[DataLength];
            for (int ind = 0; ind < DataLength; ind++)
            {
                dat[ind] = RAMData[SrcStartAdr + ind];
            }
            ms.MemPnt = dat;

            //BytCnt = (STEAM_STEP * 32) >> 11;
            BytCnt = 0x40;  // SegaSonic Arcade: Run! Run! Run! needs such a high value
            if (ms.CurAddr + BytCnt > ms.EndAddr)
            {
                BytCnt = (UInt16)(ms.EndAddr - ms.CurAddr);
            }

            //memcpy(chip.data + ms.CurAddr, ms.MemPnt + (ms.CurAddr - ms.BaseAddr), BytCnt);
            Array.Copy(ms.MemPnt, (ms.CurAddr - ms.BaseAddr), chip.data, ms.CurAddr, BytCnt);
            ms.CurAddr += BytCnt;

            return;
        }
Beispiel #3
0
        /*INLINE rf5c68_state *get_safe_token(const device_config *device)
         * {
         *  assert(device != NULL);
         *  assert(device->token != NULL);
         *  assert(device->type == SOUND);
         *  assert(sound_get_type(device) == SOUND_RF5C68);
         *  return (rf5c68_state *)device->token;
         * }*/

        /************************************************/
        /*    RF5C68 stream update                      */
        /************************************************/

        private void memstream_sample_check(rf5c68_state chip, UInt32 addr, UInt16 Speed)
        {
            mem_stream ms = chip.memstrm;
            UInt32     SmplSpd;

            SmplSpd = (uint)((Speed >= 0x0800) ? (Speed >> 11) : 1);
            if (addr >= ms.CurAddr)
            {
                // Is the stream too fast? (e.g. about to catch up the output)
                if (addr - ms.CurAddr <= SmplSpd * 5)
                {
                    // Yes - delay the stream
                    ms.CurAddr -= SmplSpd * 4;
                    if (ms.CurAddr < ms.BaseAddr)
                    {
                        ms.CurAddr = ms.BaseAddr;
                    }
                }
            }
            else
            {
                // Is the stream too slow? (e.g. the output is about to catch up the stream)
                if (ms.CurAddr - addr <= SmplSpd * 5)
                {
                    if (ms.CurAddr + SmplSpd * 4 >= ms.EndAddr)
                    {
                        rf5c68_mem_stream_flush(chip);
                    }
                    else
                    {
                        //memcpy(chip.data + ms.CurAddr, ms.MemPnt + (ms.CurAddr - ms.BaseAddr), SmplSpd * 4);
                        Array.Copy(ms.MemPnt, (ms.CurAddr - ms.BaseAddr), chip.data, ms.CurAddr, SmplSpd * 4);
                        ms.CurAddr += SmplSpd * 4;
                    }
                }
            }

            return;
        }
Beispiel #4
0
        private void device_reset_rf5c68(byte ChipID)
        {
            rf5c68_state chip = RF5C68Data[ChipID];
            int          i;
            pcm_channel  chan;
            mem_stream   ms = chip.memstrm;

            // Clear the PCM memory.
            //memset(chip.data, 0x00, chip.datasize);
            for (int ind = 0; ind < chip.datasize; ind++)
            {
                chip.data[ind] = 0;
            }
            chip.enable = 0;
            chip.cbank  = 0;
            chip.wbank  = 0;

            /* clear channel registers */
            for (i = 0; i < NUM_CHANNELS; i++)
            {
                chan        = chip.chan[i];
                chan.enable = 0;
                chan.env    = 0;
                chan.pan    = 0;
                chan.start  = 0;
                chan.addr   = 0;
                chan.step   = 0;
                chan.loopst = 0;
            }

            ms.BaseAddr = 0x0000;
            ms.CurAddr  = 0x0000;
            ms.EndAddr  = 0x0000;
            ms.CurStep  = 0x0000;
            ms.MemPnt   = null;
        }
Beispiel #5
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;
             * }*/
        }