//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); }
// 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--; } }