예제 #1
0
        //WRITE8_MEMBER( ay8910_device::data_w )
        public void ay8910_device_address_data_w_ay2(address_space space, offs_t offset, u8 data, u8 mem_mask = 0xff)
        {
            ay8910_device device = (ay8910_device)subdevice("ay2");

            device.data_w(space, offset, data, mem_mask);
        }
예제 #2
0
        // device_sound_interface overrides
        //-------------------------------------------------
        //  sound_stream_update - handle a stream update
        //-------------------------------------------------
        public override void sound_stream_update(sound_stream stream, ListPointer <stream_sample_t> [] inputs, ListPointer <stream_sample_t> [] outputs, int samples)
        {
            ay8910_device ay8910 = (ay8910_device)device();

            ListPointer <stream_sample_t> [] buf = new ListPointer <stream_sample_t> [ay8910_device.NUM_CHANNELS];  //stream_sample_t *buf[NUM_CHANNELS];
            int chan;

            buf[0] = new ListPointer <stream_sample_t>(outputs[0]);
            buf[1] = null;
            buf[2] = null;
            if (ay8910.m_streams == ay8910_device.NUM_CHANNELS)
            {
                buf[1] = outputs[1];
                buf[2] = outputs[2];
            }

            /* hack to prevent us from hanging when starting filtered outputs */
            if (ay8910.m_ready == 0)
            {
                for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                {
                    if (buf[chan] != null)
                    {
                        memset(buf[chan], 0, (UInt32)samples);  //memset(buf[chan], 0, samples * sizeof_(*buf[chan]));
                    }
                }
            }

            /* The 8910 has three outputs, each output is the mix of one of the three */
            /* tone generators and of the (single) noise generator. The two are mixed */
            /* BEFORE going into the DAC. The formula to mix each channel is: */
            /* (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable). */
            /* Note that this means that if both tone and noise are disabled, the output */
            /* is 1, not 0, and can be modulated changing the volume. */

            /* buffering loop */
            while (samples != 0)
            {
                for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                {
                    ay8910.m_count[chan]++;
                    if (ay8910.m_count[chan] >= ay8910.TONE_PERIOD(chan))
                    {
                        ay8910.m_output[chan] ^= 1;
                        ay8910.m_count[chan]   = 0;
                    }
                }

                ay8910.m_count_noise++;
                if (ay8910.m_count_noise >= ay8910.NOISE_PERIOD())
                {
                    /* toggle the prescaler output. Noise is no different to
                     * channels.
                     */
                    ay8910.m_count_noise     = 0;
                    ay8910.m_prescale_noise ^= 1;

                    if (ay8910.m_prescale_noise != 0)
                    {
                        /* The Random Number Generator of the 8910 is a 17-bit shift */
                        /* register. The input to the shift register is bit0 XOR bit3 */
                        /* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */

                        ay8910.m_rng  ^= (((ay8910.m_rng & 1) ^ ((ay8910.m_rng >> 3) & 1)) << 17);
                        ay8910.m_rng >>= 1;
                    }
                }

                for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                {
                    ay8910.m_vol_enabled[chan] = (byte)((ay8910.m_output[chan] | ay8910.TONE_ENABLEQ(chan)) & (ay8910.NOISE_OUTPUT() | ay8910.NOISE_ENABLEQ(chan)));
                }

                /* update envelope */
                if (ay8910.m_holding == 0)
                {
                    ay8910.m_count_env++;
                    if (ay8910.m_count_env >= ay8910.ENVELOPE_PERIOD() * ay8910.m_step)
                    {
                        ay8910.m_count_env = 0;
                        ay8910.m_env_step--;

                        /* check envelope current position */
                        if (ay8910.m_env_step < 0)
                        {
                            if (ay8910.m_hold != 0)
                            {
                                if (ay8910.m_alternate != 0)
                                {
                                    ay8910.m_attack ^= ay8910.m_env_step_mask;
                                }
                                ay8910.m_holding  = 1;
                                ay8910.m_env_step = 0;
                            }
                            else
                            {
                                /* if CountEnv has looped an odd number of times (usually 1), */
                                /* invert the output. */
                                if (ay8910.m_alternate != 0 && (ay8910.m_env_step & (ay8910.m_env_step_mask + 1)) != 0)
                                {
                                    ay8910.m_attack ^= ay8910.m_env_step_mask;
                                }

                                ay8910.m_env_step &= (sbyte)ay8910.m_env_step_mask;
                            }
                        }
                    }
                }
                ay8910.m_env_volume = (UInt32)(ay8910.m_env_step ^ ay8910.m_attack);

                if (ay8910.m_streams == 3)
                {
                    for (chan = 0; chan < ay8910_device.NUM_CHANNELS; chan++)
                    {
                        if (ay8910.TONE_ENVELOPE(chan) != 0)
                        {
                            if (ay8910.type() == ay8914_device.AY8914)                                                                                                  // AY8914 Has a two bit tone_envelope field
                            {
                                buf[chan][0] = ay8910.m_env_table[chan, ay8910.m_vol_enabled[chan] != 0 ? ay8910.m_env_volume >> (3 - ay8910.TONE_ENVELOPE(chan)) : 0]; // *(buf[chan]++)
                                buf[chan]++;
                            }
                            else
                            {
                                buf[chan][0] = ay8910.m_env_table[chan, ay8910.m_vol_enabled[chan] != 0 ? ay8910.m_env_volume : 0];  // *(buf[chan]++)
                                buf[chan]++;
                            }
                        }
                        else
                        {
                            buf[chan][0] = ay8910.m_vol_table[chan, ay8910.m_vol_enabled[chan] != 0 ? ay8910.TONE_VOLUME(chan) : 0];  // *(buf[chan]++)
                            buf[chan]++;
                        }
                    }
                }
                else
                {
                    buf[0][0] = ay8910.mix_3D();  // *(buf[0]++)
                    buf[0]++;
                }

                samples--;
            }
        }