Beispiel #1
0
        /*INLINE k051649_state *get_safe_token(running_device *device)
         * {
         *  assert(device != NULL);
         *  assert(device->type() == K051649);
         *  return (k051649_state *)downcast<legacy_device_base *>(device)->token();
         * }*/

        /* build a table to divide by the number of voices */
        private static void make_mixer_table(/*running_machine *machine,*/ k051649_state info, Int32 voices)
        {
            Int32 count = voices * 256;
            Int32 i;

            /* allocate memory */
            //info->mixer_table = auto_alloc_array(machine, INT16, 512 * voices);
            info.mixer_table     = new Int16[2 * count];// (INT16*)malloc(sizeof(INT16) * 2 * count);
            info.ptr_mixer_table = 0;

            /* find the middle of the table */
            info.ptr_mixer_lookup = count;

            /* fill in the table - 16 bit case */
            for (i = 0; i < count; i++)
            {
                Int32 val = i * DEF_GAIN * 16 / voices;
                //if (val > 32767) val = 32767;
                if (val > 32768)
                {
                    val = 32768;
                }
                info.mixer_table[info.ptr_mixer_lookup + i] = (Int16)val;
                info.mixer_table[info.ptr_mixer_lookup - i] = (Int16)(-val);
            }
        }
Beispiel #2
0
        //WRITE8_DEVICE_HANDLER( k051649_frequency_w )
        private void k051649_frequency_w(byte ChipID, Int32 offset, byte data)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state         info = SCC1Data[ChipID];
            k051649_sound_channel chn  = info.channel_list[offset >> 1];

            //stream_update(info->stream);

            // test-register bit 5 resets the internal counter
            if ((info.test & 0x20) != 0)
            {
                chn.counter = 0xffffffffffffffff;//~0
            }
            else if (chn.frequency < 9)
            {
                chn.counter |= ((1 << FREQ_BITS) - 1);
            }

            // update frequency
            if ((offset & 1) != 0)
            {
                chn.frequency = (chn.frequency & 0x0FF) | ((data << 8) & 0xF00);
            }
            else
            {
                chn.frequency = (chn.frequency & 0xF00) | (data << 0);
            }
            chn.counter &= 0xFFFF0000; // Valley Bell: Behaviour according to openMSX
        }
Beispiel #3
0
        //WRITE8_DEVICE_HANDLER( k051649_volume_w )
        private void k051649_volume_w(byte ChipID, Int32 offset, byte data)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state info = SCC1Data[ChipID];

            //stream_update(info->stream);
            info.channel_list[offset & 0x7].volume = data & 0xf;
        }
Beispiel #4
0
        private void device_stop_k051649(byte ChipID)
        {
            k051649_state info = SCC1Data[ChipID];

            //free(info->mixer_buffer);
            //free(info->mixer_table);

            return;
        }
Beispiel #5
0
        private void k051649_set_mute_mask(byte ChipID, UInt32 MuteMask)
        {
            k051649_state info = SCC1Data[ChipID];
            byte          CurChn;

            for (CurChn = 0; CurChn < 5; CurChn++)
            {
                info.channel_list[CurChn].Muted = (byte)((MuteMask >> CurChn) & 0x01);
            }

            return;
        }
Beispiel #6
0
        //READ8_DEVICE_HANDLER ( k052539_waveform_r )
        private byte k052539_waveform_r(byte ChipID, Int32 offset)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state info = SCC1Data[ChipID];

            // test-register bit 6 exposes the internal counter
            if ((info.test & 0x40) != 0)
            {
                //stream_update(info->stream);
                offset += (Int32)((info.channel_list[offset >> 5].counter >> FREQ_BITS));
            }
            return((byte)info.channel_list[offset >> 5].waveram[offset & 0x1f]);
        }
Beispiel #7
0
        //WRITE8_DEVICE_HANDLER( k051649_keyonoff_w )
        private void k051649_keyonoff_w(byte ChipID, Int32 offset, byte data)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state info = SCC1Data[ChipID];
            int           i;

            //stream_update(info->stream);

            for (i = 0; i < 5; i++)
            {
                info.channel_list[i].key = data & 1;
                data >>= 1;
            }
        }
Beispiel #8
0
        /* SY 20001114: Channel 5 doesn't share the waveform with channel 4 on this chip */
        //WRITE8_DEVICE_HANDLER( k052539_waveform_w )
        private void k052539_waveform_w(byte ChipID, Int32 offset, byte data)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state info = SCC1Data[ChipID];

            // waveram is read-only?
            if ((info.test & 0x40) != 0)
            {
                return;
            }

            //stream_update(info->stream);
            info.channel_list[offset >> 5].waveram[offset & 0x1f] = (sbyte)data;
        }
Beispiel #9
0
        private void k051649_w(byte ChipID, int offset, byte data)
        {
            k051649_state info = SCC1Data[ChipID];

            if (info == null)
            {
                return;
            }

            switch (offset & 1)
            {
            case 0x00:
                info.cur_reg = data;
                break;

            case 0x01:
                switch (offset >> 1)
                {
                case 0x00:
                    k051649_waveform_w(ChipID, info.cur_reg, data);
                    break;

                case 0x01:
                    k051649_frequency_w(ChipID, info.cur_reg, data);
                    break;

                case 0x02:
                    k051649_volume_w(ChipID, info.cur_reg, data);
                    break;

                case 0x03:
                    k051649_keyonoff_w(ChipID, info.cur_reg, data);
                    break;

                case 0x04:
                    k052539_waveform_w(ChipID, info.cur_reg, data);
                    break;

                case 0x05:
                    k051649_test_w(ChipID, info.cur_reg, data);
                    break;
                }
                break;
            }

            return;
        }
Beispiel #10
0
        public override uint Start(byte ChipID, uint SamplingRate, uint clock, params object[] Option)
        {
            if (SCC1Data[ChipID] == null)
            {
                SCC1Data[ChipID] = new k051649_state();
                for (int i = 0; i < SCC1Data[ChipID].channel_list.Length; i++)
                {
                    SCC1Data[ChipID].channel_list[i] = new k051649_sound_channel();
                }
            }

            UInt32 sampRate = (UInt32)device_start_k051649(ChipID, (Int32)clock);

            //int flags = 1;
            //if (Option != null && Option.Length > 0) flags = (int)(byte)Option[0];
            //k054539_init_flags(ChipID, flags);

            return(sampRate);
        }
Beispiel #11
0
        //static DEVICE_RESET( k051649 )
        private void device_reset_k051649(byte ChipID)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state info = SCC1Data[ChipID];

            k051649_sound_channel[] voice = info.channel_list;
            Int32 i;

            // reset all the voices
            for (i = 0; i < 5; i++)
            {
                voice[i].frequency = 0;
                voice[i].volume    = 0;
                voice[i].counter   = 0;
                voice[i].key       = 0;
            }

            // other parameters
            info.test    = 0x00;
            info.cur_reg = 0x00;

            return;
        }
Beispiel #12
0
        /********************************************************************************/

        //WRITE8_DEVICE_HANDLER( k051649_waveform_w )
        private void k051649_waveform_w(byte ChipID, Int32 offset, byte data)
        {
            //k051649_state *info = get_safe_token(device);
            k051649_state info = SCC1Data[ChipID];

            // waveram is read-only?
            if (((info.test & 0x40) != 0) || (((info.test & 0x80) != 0) && offset >= 0x60))
            {
                return;
            }

            //stream_update(info->stream);

            if (offset >= 0x60)
            {
                // channel 5 shares waveram with channel 4
                info.channel_list[3].waveram[offset & 0x1f] = (sbyte)data;
                info.channel_list[4].waveram[offset & 0x1f] = (sbyte)data;
            }
            else
            {
                info.channel_list[offset >> 5].waveram[offset & 0x1f] = (sbyte)data;
            }
        }
Beispiel #13
0
        //WRITE8_MEMBER( k051649_device::k051649_test_w )
        private void k051649_test_w(byte ChipID, Int32 offset, byte data)
        {
            k051649_state info = SCC1Data[ChipID];

            info.test = data;
        }
Beispiel #14
0
        /* generate sound to the mix buffer */
        //static STREAM_UPDATE( k051649_update )
        private void k051649_update(byte ChipID, Int32[][] outputs, Int32 samples)
        {
            //k051649_state *info = (k051649_state *)param;
            k051649_state info = SCC1Data[ChipID];

            k051649_sound_channel[] voice = info.channel_list;
            Int32[] buffer  = outputs[0];
            Int32[] buffer2 = outputs[1];
            Int16[] mix;
            Int32   ptr_mix = 0;
            Int32   i, j;

            // zap the contents of the mixer buffer
            //memset(info->mixer_buffer, 0, samples * sizeof(short));
            if (info.mixer_buffer == null || info.mixer_buffer.Length < samples)
            {
                info.mixer_buffer = new Int16[samples];
            }
            for (i = 0; i < samples; i++)
            {
                info.mixer_buffer[i] = 0;
            }

            for (j = 0; j < 5; j++)
            {
                // channel is halted for freq < 9
                if (voice[j].frequency > 8 && voice[j].Muted == 0)
                {
                    sbyte[] w = voice[j].waveram;            /* 19991207.CAB */
                    Int32   v = voice[j].volume * voice[j].key;
                    Int32   c = (Int32)voice[j].counter;
                    /* Amuse source:  Cab suggests this method gives greater resolution */
                    /* Sean Young 20010417: the formula is really: f = clock/(16*(f+1))*/
                    Int32 step = (Int32)(((Int64)info.mclock * (1 << FREQ_BITS)) / (float)((voice[j].frequency + 1) * 16 * (info.rate / 32)) + 0.5);

                    mix     = info.mixer_buffer;
                    ptr_mix = 0;

                    // add our contribution
                    for (i = 0; i < samples; i++)
                    {
                        Int32 offs;

                        c              += step;
                        offs            = (c >> FREQ_BITS) & 0x1f;
                        mix[ptr_mix++] += (Int16)((w[offs] * v) >> 3);
                    }

                    // update the counter for this voice
                    voice[j].counter = (UInt64)c;
                }
            }

            // mix it down
            mix     = info.mixer_buffer;
            ptr_mix = 0;
            for (i = 0; i < samples; i++)
            {
                buffer[i] = buffer2[i] = info.mixer_table[info.ptr_mixer_lookup + mix[ptr_mix++]];
                i++;
            }
        }