Esempio n. 1
0
        //WRITE8_DEVICE_HANDLER( saa1099_control_w )
        private void saa1099_control_w(byte ChipID, int offset, byte data)
        {
            //saa1099_state *saa = get_safe_token(device);
            _saa1099_state saa = SAA1099Data[ChipID];

            if ((data & 0xff) > 0x1c)
            {
                /* Error! */
                //throw new Exception("SAA1099: Unknown register selected\n");
            }

            saa.selected_reg = data & 0x1f;
            if (saa.selected_reg == 0x18 || saa.selected_reg == 0x19)
            {
                /* clock the envelope channels */
                if (saa.env_clock[0] != 0)
                {
                    saa1099_envelope(saa, 0);
                }
                if (saa.env_clock[1] != 0)
                {
                    saa1099_envelope(saa, 1);
                }
            }
        }
Esempio n. 2
0
        private void saa1099_set_mute_mask(byte ChipID, uint MuteMask)
        {
            _saa1099_state saa = SAA1099Data[ChipID];
            byte           CurChn;

            for (CurChn = 0; CurChn < 6; CurChn++)
            {
                saa.channels[CurChn].Muted = (byte)((MuteMask >> CurChn) & 0x01);
            }

            return;
        }
Esempio n. 3
0
        private void device_reset_saa1099(byte ChipID)
        {
            _saa1099_state saa = SAA1099Data[ChipID];

            saa1099_channel sachn;
            byte            CurChn;

            for (CurChn = 0; CurChn < 6; CurChn++)
            {
                sachn              = saa.channels[CurChn];
                sachn.frequency    = 0;
                sachn.octave       = 0;
                sachn.amplitude[0] = 0;
                sachn.amplitude[1] = 0;
                sachn.envelope[0]  = 0;
                sachn.envelope[1]  = 0;
                sachn.freq_enable  = 0;
                sachn.noise_enable = 0;

                sachn.counter = 0;
                sachn.freq    = 0;
                sachn.level   = 0;
            }
            for (CurChn = 0; CurChn < 2; CurChn++)
            {
                saa.noise[CurChn].counter = 0;
                saa.noise[CurChn].freq    = 0;
                saa.noise[CurChn].level   = 0;

                saa.noise_params[1]           = 0x00;
                saa.env_reverse_right[CurChn] = 0x00;
                saa.env_mode[CurChn]          = 0x00;
                saa.env_bits[CurChn]          = 0x00;
                saa.env_clock[CurChn]         = 0x00;
                saa.env_enable[CurChn]        = 0x00;
                saa.env_step[CurChn]          = 0;
            }

            saa.all_ch_enable = 0x00;
            saa.sync_state    = 0x00;

            return;
        }
Esempio n. 4
0
        };                                                                                                             // MAX_CHIPS];

        //private _saa1099_state get_safe_token(device_t device)
        //{
        //    assert(device != NULL);
        //    assert(device->type() == SAA1099);
        //    return (saa1099_state*)downcast<legacy_device_base*>(device)->token();
        //}


        private void saa1099_envelope(_saa1099_state saa, int ch)
        {
            if (saa.env_enable[ch] != 0)
            {
                int step, mode, mask;
                mode = saa.env_mode[ch];
                /* step from 0..63 and then loop in steps 32..63 */
                step = saa.env_step[ch] =
                    ((saa.env_step[ch] + 1) & 0x3f) | (saa.env_step[ch] & 0x20);

                mask = 15;
                if (saa.env_bits[ch] != 0)
                {
                    mask &= ~1;     /* 3 bit resolution, mask LSB */
                }
                saa.channels[ch * 3 + 0].envelope[LEFT]         =
                    saa.channels[ch * 3 + 1].envelope[LEFT]     =
                        saa.channels[ch * 3 + 2].envelope[LEFT] = envelope[mode][step] & mask;
                if ((saa.env_reverse_right[ch] & 0x01) != 0)
                {
                    saa.channels[ch * 3 + 0].envelope[RIGHT]         =
                        saa.channels[ch * 3 + 1].envelope[RIGHT]     =
                            saa.channels[ch * 3 + 2].envelope[RIGHT] = (15 - envelope[mode][step]) & mask;
                }
                else
                {
                    saa.channels[ch * 3 + 0].envelope[RIGHT]         =
                        saa.channels[ch * 3 + 1].envelope[RIGHT]     =
                            saa.channels[ch * 3 + 2].envelope[RIGHT] = envelope[mode][step] & mask;
                }
            }
            else
            {
                /* envelope mode off, set all envelope factors to 16 */
                saa.channels[ch * 3 + 0].envelope[LEFT]                      =
                    saa.channels[ch * 3 + 1].envelope[LEFT]                  =
                        saa.channels[ch * 3 + 2].envelope[LEFT]              =
                            saa.channels[ch * 3 + 0].envelope[RIGHT]         =
                                saa.channels[ch * 3 + 1].envelope[RIGHT]     =
                                    saa.channels[ch * 3 + 2].envelope[RIGHT] = 16;
            }
        }
Esempio n. 5
0
        //WRITE8_DEVICE_HANDLER( saa1099_data_w )
        private void saa1099_data_w(byte ChipID, int offset, byte data)
        {
            //saa1099_state *saa = get_safe_token(device);
            _saa1099_state saa = SAA1099Data[ChipID];
            int            reg = saa.selected_reg;
            int            ch;

            /* first update the stream to this point in time */
            //saa.stream->update();

            switch (reg)
            {
            /* channel i amplitude */
            case 0x00:
            case 0x01:
            case 0x02:
            case 0x03:
            case 0x04:
            case 0x05:
                ch = reg & 7;
                saa.channels[ch].amplitude[LEFT]  = amplitude_lookup[data & 0x0f];
                saa.channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f];
                break;

            /* channel i frequency */
            case 0x08:
            case 0x09:
            case 0x0a:
            case 0x0b:
            case 0x0c:
            case 0x0d:
                ch = reg & 7;
                saa.channels[ch].frequency = data & 0xff;
                break;

            /* channel i octave */
            case 0x10:
            case 0x11:
            case 0x12:
                ch = (reg - 0x10) << 1;
                saa.channels[ch + 0].octave = data & 0x07;
                saa.channels[ch + 1].octave = (data >> 4) & 0x07;
                break;

            /* channel i frequency enable */
            case 0x14:
                saa.channels[0].freq_enable = data & 0x01;
                saa.channels[1].freq_enable = data & 0x02;
                saa.channels[2].freq_enable = data & 0x04;
                saa.channels[3].freq_enable = data & 0x08;
                saa.channels[4].freq_enable = data & 0x10;
                saa.channels[5].freq_enable = data & 0x20;
                break;

            /* channel i noise enable */
            case 0x15:
                saa.channels[0].noise_enable = data & 0x01;
                saa.channels[1].noise_enable = data & 0x02;
                saa.channels[2].noise_enable = data & 0x04;
                saa.channels[3].noise_enable = data & 0x08;
                saa.channels[4].noise_enable = data & 0x10;
                saa.channels[5].noise_enable = data & 0x20;
                break;

            /* noise generators parameters */
            case 0x16:
                saa.noise_params[0] = data & 0x03;
                saa.noise_params[1] = (data >> 4) & 0x03;
                break;

            /* envelope generators parameters */
            case 0x18:
            case 0x19:
                ch = reg - 0x18;
                saa.env_reverse_right[ch] = data & 0x01;
                saa.env_mode[ch]          = (data >> 1) & 0x07;
                saa.env_bits[ch]          = data & 0x10;
                saa.env_clock[ch]         = data & 0x20;
                saa.env_enable[ch]        = data & 0x80;
                /* reset the envelope */
                saa.env_step[ch] = 0;
                break;

            /* channels enable & reset generators */
            case 0x1c:
                saa.all_ch_enable = data & 0x01;
                saa.sync_state    = data & 0x02;
                if ((data & 0x02) != 0)
                {
                    int i;

                    /* Synch & Reset generators */
                    //throw new Exception("SAA1099: -reg 0x1c- Chip reset\n");
                    for (i = 0; i < 6; i++)
                    {
                        saa.channels[i].level   = 0;
                        saa.channels[i].counter = 0.0;
                    }
                }
                break;

            default:        /* Error! */
                //throw new Exception(string.Format("SAA1099: Unknown operation (reg:{0:x02}, data:{1:x02})\n", reg, data));
                break;
            }
        }
Esempio n. 6
0
        private void device_stop_saa1099(byte ChipID)
        {
            _saa1099_state saa = SAA1099Data[ChipID];

            return;
        }
Esempio n. 7
0
        //static STREAM_UPDATE( saa1099_update )
        private void saa1099_update(byte ChipID, int[][] outputs, int samples)
        {
            //saa1099_state *saa = (saa1099_state *)param;
            _saa1099_state saa = SAA1099Data[ChipID];
            int            j, ch;
            int            clk2div512;

            /* if the channels are disabled we're done */
            if (saa.all_ch_enable == 0)
            {
                /* init output data */
                for (int i = 0; i < samples; i++)
                {
                    outputs[LEFT][i]  = 0;
                    outputs[RIGHT][i] = 0;
                }
                return;
            }

            for (ch = 0; ch < 2; ch++)
            {
                switch (saa.noise_params[ch])
                {
                case 0: saa.noise[ch].freq = saa.master_clock / 256.0 * 2; break;

                case 1: saa.noise[ch].freq = saa.master_clock / 512.0 * 2; break;

                case 2: saa.noise[ch].freq = saa.master_clock / 1024.0 * 2; break;

                case 3: saa.noise[ch].freq = saa.channels[ch * 3].freq; break;
                }
            }

            // clock fix thanks to http://www.vogons.org/viewtopic.php?p=344227#p344227
            //clk2div512 = 2 * saa.master_clock / 512;
            clk2div512 = (saa.master_clock + 128) / 256;

            /* fill all data needed */
            for (j = 0; j < samples; j++)
            {
                int output_l = 0, output_r = 0;

                /* for each channel */
                for (ch = 0; ch < 6; ch++)
                {
                    if (saa.channels[ch].freq == 0.0)
                    {
                        saa.channels[ch].freq = (double)(clk2div512 << saa.channels[ch].octave) /
                                                (511.0 - (double)saa.channels[ch].frequency);
                    }

                    /* check the actual position in the square wave */
                    saa.channels[ch].counter -= saa.channels[ch].freq;
                    while (saa.channels[ch].counter < 0)
                    {
                        /* calculate new frequency now after the half wave is updated */
                        saa.channels[ch].freq = (double)(clk2div512 << saa.channels[ch].octave) /
                                                (511.0 - (double)saa.channels[ch].frequency);

                        saa.channels[ch].counter += saa.sample_rate;
                        saa.channels[ch].level   ^= 1;

                        /* eventually clock the envelope counters */
                        if (ch == 1 && saa.env_clock[0] == 0)
                        {
                            saa1099_envelope(saa, 0);
                        }
                        if (ch == 4 && saa.env_clock[1] == 0)
                        {
                            saa1099_envelope(saa, 1);
                        }
                    }

                    if (saa.channels[ch].Muted != 0)
                    {
                        continue;   // placed here to ensure that envelopes are updated
                    }
#if false
                    // if the noise is enabled
                    if (saa.channels[ch].noise_enable != 0)
                    {
                        // if the noise level is high (noise 0: chan 0-2, noise 1: chan 3-5)
                        if ((saa.noise[ch / 3].level & 1) != 0)
                        {
                            // subtract to avoid overflows, also use only half amplitude
                            output_l -= saa.channels[ch].amplitude[LEFT] * saa.channels[ch].envelope[LEFT] / 16 / 2;
                            output_r -= saa.channels[ch].amplitude[RIGHT] * saa.channels[ch].envelope[RIGHT] / 16 / 2;
                        }
                    }

                    // if the square wave is enabled
                    if (saa.channels[ch].freq_enable != 0)
                    {
                        // if the channel level is high
                        if ((saa.channels[ch].level & 1) != 0)
                        {
                            output_l += saa.channels[ch].amplitude[LEFT] * saa.channels[ch].envelope[LEFT] / 16;
                            output_r += saa.channels[ch].amplitude[RIGHT] * saa.channels[ch].envelope[RIGHT] / 16;
                        }
                    }
#else
                    // Now with bipolar output. -Valley Bell
                    if (saa.channels[ch].noise_enable != 0)
                    {
                        if ((saa.noise[ch / 3].level & 1) != 0)
                        {
                            output_l += saa.channels[ch].amplitude[LEFT] * saa.channels[ch].envelope[LEFT] / 32 / 2;
                            output_r += saa.channels[ch].amplitude[RIGHT] * saa.channels[ch].envelope[RIGHT] / 32 / 2;
                        }
                        else
                        {
                            output_l -= saa.channels[ch].amplitude[LEFT] * saa.channels[ch].envelope[LEFT] / 32 / 2;
                            output_r -= saa.channels[ch].amplitude[RIGHT] * saa.channels[ch].envelope[RIGHT] / 32 / 2;
                        }
                    }

                    if (saa.channels[ch].freq_enable != 0)
                    {
                        if ((saa.channels[ch].level & 1) != 0)
                        {
                            output_l += saa.channels[ch].amplitude[LEFT] * saa.channels[ch].envelope[LEFT] / 32;
                            output_r += saa.channels[ch].amplitude[RIGHT] * saa.channels[ch].envelope[RIGHT] / 32;
                        }
                        else
                        {
                            output_l -= saa.channels[ch].amplitude[LEFT] * saa.channels[ch].envelope[LEFT] / 32;
                            output_r -= saa.channels[ch].amplitude[RIGHT] * saa.channels[ch].envelope[RIGHT] / 32;
                        }
                    }
#endif
                }

                for (ch = 0; ch < 2; ch++)
                {
                    /* check the actual position in noise generator */
                    saa.noise[ch].counter -= saa.noise[ch].freq;
                    while (saa.noise[ch].counter < 0)
                    {
                        saa.noise[ch].counter += saa.sample_rate;
                        if (((saa.noise[ch].level & 0x4000) == 0) == ((saa.noise[ch].level & 0x0040) == 0))
                        {
                            saa.noise[ch].level = (saa.noise[ch].level << 1) | 1;
                        }
                        else
                        {
                            saa.noise[ch].level <<= 1;
                        }
                    }
                }
                /* write sound data to the buffer */
                outputs[LEFT][j]  = output_l / 6;
                outputs[RIGHT][j] = output_r / 6;
            }

            visVolume[ChipID][0][0] = outputs[0][0];
            visVolume[ChipID][0][1] = outputs[1][0];
        }