Пример #1
0
        // The gate bit is handled by the EnvelopeGenerator.


        public WaveformGenerator()
        {
            sync_source = this;

            set_chip_model(SIDDefs.chip_model.MOS6581);

            reset();
        }
Пример #2
0
        public Voice()
        {
            wave = new WaveformGenerator();
            envelope = new EnvelopeGenerator();

            muted = false;
            set_chip_model(SIDDefs.chip_model.MOS6581);
        }
Пример #3
0
        // deserializing
        protected void LoadFromReader(BinaryReader reader)
        {
            wave = new WaveformGenerator(reader);
            envelope = new EnvelopeGenerator(reader);

            muted = reader.ReadBoolean();
            wave_zero = reader.ReadInt32();
            voice_DC = reader.ReadInt32();
        }
Пример #4
0
        public void UpdateAfterLoad(Voice v0, Voice v1, Voice v2)
        {
            switch (sync_source_id)
            {
            case 0:
                sync_source = v0.wave;
                break;

            case 1:
                sync_source = v1.wave;
                break;

            case 2:
                sync_source = v2.wave;
                break;

            default:
#if DEBUG
                throw new Exception("unknown Source_WaveID: " + sync_source_id.ToString());
#endif
            case -1:
                sync_source = null;
                break;
            }

            switch (sync_dest_id)
            {
            case 0:
                sync_dest = v0.wave;
                break;

            case 1:
                sync_dest = v1.wave;
                break;

            case 2:
                sync_dest = v2.wave;
                break;

            default:
#if DEBUG
                throw new Exception("unknown Dest_WaveID: " + sync_dest_id.ToString());
#endif
            case -1:
                sync_dest = null;
                break;
            }
        }
Пример #5
0
 public void set_sync_source(WaveformGenerator source)
 {
     sync_source      = source;
     source.sync_dest = this;
 }
Пример #6
0
        /// <summary>
        /// SID clocking - delta_t cycles
        /// </summary>
        /// <param name="delta_t"></param>
        public void clock(int delta_t)
        {
            if (delta_t <= 0)
            {
                return;
            }

            // Age bus value.
            bus_value_ttl -= delta_t;
            if (bus_value_ttl <= 0)
            {
                bus_value     = 0;
                bus_value_ttl = 0;
            }

            // Clock amplitude modulators.
            voice0.envelope.clock(delta_t);
            voice1.envelope.clock(delta_t);
            voice2.envelope.clock(delta_t);

            // Clock and synchronize oscillators.
            // Loop until we reach the current cycle.
            int delta_t_osc = delta_t;

            while (delta_t_osc != 0)
            {
                int delta_t_min = delta_t_osc;

                // Find minimum number of cycles to an oscillator accumulator MSB toggle.
                // We have to clock on each MSB on / MSB off for hard sync to operate correctly.
                WaveformGenerator wave = voice0.wave;

                // It is only necessary to clock on the MSB of an oscillator
                // that is a sync source and has freq != 0.
                if ((wave.sync_dest.sync != 0) && (wave.freq != 0))
                {
                    int freq        = wave.freq;
                    int accumulator = wave.accumulator;

                    // Clock on MSB off if MSB is on, clock on MSB on if MSB is off.
                    int delta_accumulator = ((accumulator & 0x800000) != 0 ? 0x1000000 : 0x800000) - accumulator;

                    int delta_t_next = (delta_accumulator / freq);
                    if ((delta_accumulator % freq) != 0)
                    {
                        ++delta_t_next;
                    }

                    if (delta_t_next < delta_t_min)
                    {
                        delta_t_min = delta_t_next;
                    }
                }

                wave = voice1.wave;

                // It is only necessary to clock on the MSB of an oscillator
                // that is a sync source and has freq != 0.
                if ((wave.sync_dest.sync != 0) && (wave.freq != 0))
                {
                    int freq        = wave.freq;
                    int accumulator = wave.accumulator;

                    // Clock on MSB off if MSB is on, clock on MSB on if MSB is off.
                    int delta_accumulator = ((accumulator & 0x800000) != 0 ? 0x1000000 : 0x800000) - accumulator;

                    int delta_t_next = (delta_accumulator / freq);
                    if ((delta_accumulator % freq) != 0)
                    {
                        ++delta_t_next;
                    }

                    if (delta_t_next < delta_t_min)
                    {
                        delta_t_min = delta_t_next;
                    }
                }

                wave = voice2.wave;

                // It is only necessary to clock on the MSB of an oscillator
                // that is a sync source and has freq != 0.
                if ((wave.sync_dest.sync != 0) && (wave.freq != 0))
                {
                    int freq        = wave.freq;
                    int accumulator = wave.accumulator;

                    // Clock on MSB off if MSB is on, clock on MSB on if MSB is off.
                    int delta_accumulator = ((accumulator & 0x800000) != 0 ? 0x1000000 : 0x800000) - accumulator;

                    int delta_t_next = (delta_accumulator / freq);
                    if ((delta_accumulator % freq) != 0)
                    {
                        ++delta_t_next;
                    }

                    if (delta_t_next < delta_t_min)
                    {
                        delta_t_min = delta_t_next;
                    }
                }

                // Clock oscillators.
                voice0.wave.clock(delta_t_min);
                voice1.wave.clock(delta_t_min);
                voice2.wave.clock(delta_t_min);

                // Synchronize oscillators.
                voice0.wave.synchronize();
                voice1.wave.synchronize();
                voice2.wave.synchronize();

                delta_t_osc -= delta_t_min;
            }

            // Clock filter.
            filter.clock(delta_t, voice0.output, voice1.output, voice2.output, ext_in);

            // Clock external filter.
            extfilt.clock(delta_t, filter.output);
        }
Пример #7
0
        public InternalState read_state()
        {
            InternalState state = new InternalState();
            int           j     = 0;

            WaveformGenerator wave     = voice0.wave;
            EnvelopeGenerator envelope = voice0.envelope;

            state.sid_register[j + 0] = (char)(wave.freq & 0xff);
            state.sid_register[j + 1] = (char)(wave.freq >> 8);
            state.sid_register[j + 2] = (char)(wave.pw & 0xff);
            state.sid_register[j + 3] = (char)(wave.pw >> 8);
            state.sid_register[j + 4] = (char)((wave.waveform << 4) | ((wave.test != 0) ? 0x08 : 0) | ((wave.ring_mod != 0) ? 0x04 : 0) | ((wave.sync != 0) ? 0x02 : 0) | ((envelope.gate != 0) ? 0x01 : 0));
            state.sid_register[j + 5] = (char)((envelope.attack << 4) | envelope.decay);
            state.sid_register[j + 6] = (char)((envelope.sustain << 4) | envelope.release);

            j++;
            wave     = voice1.wave;
            envelope = voice1.envelope;
            state.sid_register[j + 0] = (char)(wave.freq & 0xff);
            state.sid_register[j + 1] = (char)(wave.freq >> 8);
            state.sid_register[j + 2] = (char)(wave.pw & 0xff);
            state.sid_register[j + 3] = (char)(wave.pw >> 8);
            state.sid_register[j + 4] = (char)((wave.waveform << 4) | ((wave.test != 0) ? 0x08 : 0) | ((wave.ring_mod != 0) ? 0x04 : 0) | ((wave.sync != 0) ? 0x02 : 0) | ((envelope.gate != 0) ? 0x01 : 0));
            state.sid_register[j + 5] = (char)((envelope.attack << 4) | envelope.decay);
            state.sid_register[j + 6] = (char)((envelope.sustain << 4) | envelope.release);

            j++;
            wave     = voice2.wave;
            envelope = voice2.envelope;
            state.sid_register[j + 0] = (char)(wave.freq & 0xff);
            state.sid_register[j + 1] = (char)(wave.freq >> 8);
            state.sid_register[j + 2] = (char)(wave.pw & 0xff);
            state.sid_register[j + 3] = (char)(wave.pw >> 8);
            state.sid_register[j + 4] = (char)((wave.waveform << 4) | ((wave.test != 0) ? 0x08 : 0) | ((wave.ring_mod != 0) ? 0x04 : 0) | ((wave.sync != 0) ? 0x02 : 0) | ((envelope.gate != 0) ? 0x01 : 0));
            state.sid_register[j + 5] = (char)((envelope.attack << 4) | envelope.decay);
            state.sid_register[j + 6] = (char)((envelope.sustain << 4) | envelope.release);

            state.sid_register[j++] = (char)(filter.fc & 0x007);
            state.sid_register[j++] = (char)(filter.fc >> 3);
            state.sid_register[j++] = (char)((filter.res << 4) | filter.filt);
            state.sid_register[j++] = (char)(((filter.voice3off != 0) ? 0x80 : 0) | (filter.hp_bp_lp << 4) | filter.vol);

            // These registers are superfluous, but included for completeness.
            for (; j < 0x1d; j++)
            {
                state.sid_register[j] = (char)(read(j));
            }
            for (; j < 0x20; j++)
            {
                state.sid_register[j] = (char)0;
            }

            state.bus_value     = bus_value;
            state.bus_value_ttl = bus_value_ttl;

            state.accumulator0                = voice0.wave.accumulator;
            state.shift_register0             = voice0.wave.shift_register;
            state.rate_counter0               = voice0.envelope.rate_counter;
            state.rate_counter_period0        = voice0.envelope.rate_period;
            state.exponential_counter0        = voice0.envelope.exponential_counter;
            state.exponential_counter_period0 = voice0.envelope.exponential_counter_period;
            state.envelope_counter0           = voice0.envelope.envelope_counter;
            state.envelope_state0             = voice0.envelope.state;
            state.hold_zero0 = voice0.envelope.hold_zero;

            state.accumulator1                = voice1.wave.accumulator;
            state.shift_register1             = voice1.wave.shift_register;
            state.rate_counter1               = voice1.envelope.rate_counter;
            state.rate_counter_period1        = voice1.envelope.rate_period;
            state.exponential_counter1        = voice1.envelope.exponential_counter;
            state.exponential_counter_period1 = voice1.envelope.exponential_counter_period;
            state.envelope_counter1           = voice1.envelope.envelope_counter;
            state.envelope_state1             = voice1.envelope.state;
            state.hold_zero1 = voice1.envelope.hold_zero;

            state.accumulator2                = voice2.wave.accumulator;
            state.shift_register2             = voice2.wave.shift_register;
            state.rate_counter2               = voice2.envelope.rate_counter;
            state.rate_counter_period2        = voice2.envelope.rate_period;
            state.exponential_counter2        = voice2.envelope.exponential_counter;
            state.exponential_counter_period2 = voice2.envelope.exponential_counter_period;
            state.envelope_counter2           = voice2.envelope.envelope_counter;
            state.envelope_state2             = voice2.envelope.state;
            state.hold_zero2 = voice2.envelope.hold_zero;

            return(state);
        }