コード例 #1
0
        public void k053260_write_rom(byte ChipID, Int32 ROMSize, Int32 DataStart, Int32 DataLength, byte[] ROMData, Int32 SrcStartAdr)
        {
            k053260_state info = K053260Data[ChipID];

            if (info.rom_size != ROMSize)
            {
                info.rom      = new byte[ROMSize];// (byte*)realloc(info.rom, ROMSize);
                info.rom_size = (UInt32)ROMSize;

                for (Int32 i = 0; i < ROMSize; i++)
                {
                    info.rom[i] = 0xff;
                }
                //memset(info.rom, 0xFF, ROMSize);
            }

            if (DataStart > ROMSize)
            {
                return;
            }
            if (DataStart + DataLength > ROMSize)
            {
                DataLength = ROMSize - DataStart;
            }

            for (Int32 i = 0; i < DataLength; i++)
            {
                info.rom[i + DataStart] = ROMData[i + SrcStartAdr];
            }
            //memcpy(info.rom + DataStart, ROMData, DataLength);

            return;
        }
コード例 #2
0
        };                                                                                                      //[MAX_CHIPS];

        /*INLINE k053260_state *get_safe_token(device_t *device)
         * {
         *  assert(device != NULL);
         *  assert(device->type() == K053260);
         *  return (k053260_state *)downcast<legacy_device_base *>(device)->token();
         * }*/


        private void InitDeltaTable(k053260_state ic, Int32 rate, Int32 clock)
        {
            Int32  i;
            double _base = (double)rate;
            double max   = (double)(clock); /* Hz */
            UInt32 val;

            for (i = 0; i < 0x1000; i++)
            {
                double v      = (double)(0x1000 - i);
                double target = (max) / v;
                double _fixed = (double)(1 << BASE_SHIFT);

                if (target != 0 && _base != 0)
                {
                    target = _fixed / (_base / target);
                    val    = (UInt32)target;
                    if (val == 0)
                    {
                        val = 1;
                    }
                }
                else
                {
                    val = 1;
                }

                ic.delta_table[i] = val;
            }
        }
コード例 #3
0
        public void device_stop_k053260(byte ChipID)
        {
            k053260_state ic = K053260Data[ChipID];

            //free(ic.delta_table);
            //free(ic.rom);
            ic.rom = null;

            return;
        }
コード例 #4
0
        public void k053260_set_mute_mask(byte ChipID, UInt32 MuteMask)
        {
            k053260_state info = K053260Data[ChipID];
            byte          CurChn;

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

            return;
        }
コード例 #5
0
        //READ8_DEVICE_HANDLER( k053260_r )
        public byte k053260_r(byte ChipID, Int32 offset)
        {
            //k053260_state *ic = get_safe_token(device);
            k053260_state ic = K053260Data[ChipID];

            switch (offset)
            {
            case 0x29:     /* channel status */
            {
                Int32 i, status = 0;

                for (i = 0; i < 4; i++)
                {
                    status |= ic.channels[i].play << i;
                }

                return((byte)status);
            }
            //break;

            case 0x2e:     /* read ROM */
                if ((ic.mode & 1) != 0)
                {
                    UInt32 offs = ic.channels[0].start + (ic.channels[0].pos >> BASE_SHIFT) + (ic.channels[0].bank << 16);

                    ic.channels[0].pos += (1 << 16);

                    if (offs > ic.rom_size)
                    {
                        //logerror("%s: K53260: Attempting to read past ROM size in ROM Read Mode (offs = %06x, size = %06x).\n", device->machine().describe_context(),offs,ic.rom_size );
                        //logerror("K53260: Attempting to read past ROM size in ROM Read Mode (offs = %06x, size = %06x).\n", offs, ic.rom_size);

                        return(0);
                    }

                    return(ic.rom[offs]);
                }
                break;
            }

            return((byte)ic.regs[offset]);
        }
コード例 #6
0
        //static DEVICE_RESET( k053260 )
        public void device_reset_k053260(byte ChipID)
        {
            //k053260_state *ic = get_safe_token(device);
            k053260_state ic = K053260Data[ChipID];
            Int32         i;

            for (i = 0; i < 4; i++)
            {
                ic.channels[i].rate      = 0;
                ic.channels[i].size      = 0;
                ic.channels[i].start     = 0;
                ic.channels[i].bank      = 0;
                ic.channels[i].volume    = 0;
                ic.channels[i].play      = 0;
                ic.channels[i].pan       = 0;
                ic.channels[i].pos       = 0;
                ic.channels[i].loop      = 0;
                ic.channels[i].ppcm      = 0;
                ic.channels[i].ppcm_data = 0;
            }
        }
コード例 #7
0
        private void check_bounds(k053260_state ic, Int32 channel)
        {
            Int32 channel_start = (Int32)((ic.channels[channel].bank << 16) + ic.channels[channel].start);
            Int32 channel_end   = (Int32)(channel_start + ic.channels[channel].size - 1);

            if (channel_start > ic.rom_size)
            {
                //logerror("K53260: Attempting to start playing past the end of the ROM ( start = %06x, end = %06x ).\n", channel_start, channel_end);

                ic.channels[channel].play = 0;

                return;
            }

            if (channel_end > ic.rom_size)
            {
                //logerror("K53260: Attempting to play past the end of the ROM ( start = %06x, end = %06x ).\n", channel_start, channel_end);

                ic.channels[channel].size = (UInt32)(ic.rom_size - channel_start);
            }
            //if (LOG) logerror("K053260: Sample Start = %06x, Sample End = %06x, Sample rate = %04x, PPCM = %s\n", channel_start, channel_end, ic.channels[channel].rate, ic.channels[channel].ppcm ? "yes" : "no");
        }
コード例 #8
0
        //WRITE8_DEVICE_HANDLER( k053260_w )
        public void k053260_w(byte ChipID, Int32 offset, byte data)
        {
            Int32 i, t;
            Int32 r = offset;
            Int32 v = data;

            //k053260_state *ic = get_safe_token(device);
            k053260_state ic = K053260Data[ChipID];

            if (r > 0x2f)
            {
                //logerror("K053260: Writing past registers\n");
                return;
            }

            //ic.channel->update();

            /* before we update the regs, we need to check for a latched reg */
            if (r == 0x28)
            {
                t = ic.regs[r] ^ v;

                for (i = 0; i < 4; i++)
                {
                    if ((t & (1 << i)) != 0)
                    {
                        if ((v & (1 << i)) != 0)
                        {
                            ic.channels[i].play      = 1;
                            ic.channels[i].pos       = 0;
                            ic.channels[i].ppcm_data = 0;
                            check_bounds(ic, i);
                        }
                        else
                        {
                            ic.channels[i].play = 0;
                        }
                    }
                }

                ic.regs[r] = v;
                return;
            }

            /* update regs */
            ic.regs[r] = v;

            /* communication registers */
            if (r < 8)
            {
                return;
            }

            /* channel setup */
            if (r < 0x28)
            {
                Int32 channel = (r - 8) / 8;

                switch ((r - 8) & 0x07)
                {
                case 0:     /* sample rate low */
                    ic.channels[channel].rate &= 0x0f00;
                    ic.channels[channel].rate |= (UInt32)v;
                    break;

                case 1:     /* sample rate high */
                    ic.channels[channel].rate &= 0x00ff;
                    ic.channels[channel].rate |= (UInt32)((v & 0x0f) << 8);
                    break;

                case 2:     /* size low */
                    ic.channels[channel].size &= 0xff00;
                    ic.channels[channel].size |= (UInt32)v;
                    break;

                case 3:     /* size high */
                    ic.channels[channel].size &= 0x00ff;
                    ic.channels[channel].size |= (UInt32)(v << 8);
                    break;

                case 4:     /* start low */
                    ic.channels[channel].start &= 0xff00;
                    ic.channels[channel].start |= (UInt32)v;
                    break;

                case 5:     /* start high */
                    ic.channels[channel].start &= 0x00ff;
                    ic.channels[channel].start |= (UInt32)(v << 8);
                    break;

                case 6:     /* bank */
                    ic.channels[channel].bank = (UInt32)(v & 0xff);
                    break;

                case 7:     /* volume is 7 bits. Convert to 8 bits now. */
                    ic.channels[channel].volume = (UInt32)(((v & 0x7f) << 1) | (v & 1));
                    break;
                }

                return;
            }

            switch (r)
            {
            case 0x2a:     /* loop, ppcm */
                for (i = 0; i < 4; i++)
                {
                    ic.channels[i].loop = (v & (1 << i)) != 0 ? 1 : 0;
                }

                for (i = 4; i < 8; i++)
                {
                    ic.channels[i - 4].ppcm = (v & (1 << i)) != 0 ? 1 : 0;
                }
                break;

            case 0x2c:     /* pan */
                ic.channels[0].pan = (UInt32)(v & 7);
                ic.channels[1].pan = (UInt32)((v >> 3) & 7);
                break;

            case 0x2d:     /* more pan */
                ic.channels[2].pan = (UInt32)(v & 7);
                ic.channels[3].pan = (UInt32)((v >> 3) & 7);
                break;

            case 0x2f:     /* control */
                ic.mode = v & 7;
                /* bit 0 = read ROM */
                /* bit 1 = enable sound output */
                /* bit 2 = unknown */
                break;
            }
        }
コード例 #9
0
        //static STREAM_UPDATE( k053260_update )
        public void k053260_update(byte ChipID, Int32[][] outputs, Int32 samples)
        {
            //sbyte[] dpcmcnv = new sbyte[] { 0, 1, 2, 4, 8, 16, 32, 64, -128, -64, -32, -16, -8, -4, -2, -1 };
            Int32 i, j;
            //Int32[] lvol = new Int32[4], rvol = new Int32[4], play = new Int32[4], loop = new Int32[4], ppcm = new Int32[4];
            //byte[] rom = new byte[4];
            //UInt32[] ptrRom = new UInt32[4];
            //UInt32[] delta = new UInt32[4], end = new UInt32[4], pos = new UInt32[4];
            //sbyte[] ppcm_data = new sbyte[4];
            Int32 dataL, dataR;
            sbyte d;
            //k053260_state *ic = (k053260_state *)param;
            k053260_state ic = K053260Data[ChipID];

            /* precache some values */
            for (i = 0; i < 4; i++)
            {
                if (ic.channels[i].Muted != 0)
                {
                    play[i] = 0;
                    continue;
                }
                //rom[i] = ic.rom[ic.channels[i].start + (ic.channels[i].bank << 16)];
                ptrRom[i]    = ic.channels[i].start + (ic.channels[i].bank << 16);
                delta[i]     = ic.delta_table[ic.channels[i].rate];
                lvol[i]      = (Int32)(ic.channels[i].volume * ic.channels[i].pan);
                rvol[i]      = (Int32)(ic.channels[i].volume * (8 - ic.channels[i].pan));
                end[i]       = ic.channels[i].size;
                pos[i]       = ic.channels[i].pos;
                play[i]      = ic.channels[i].play;
                loop[i]      = ic.channels[i].loop;
                ppcm[i]      = ic.channels[i].ppcm;
                ppcm_data[i] = (sbyte)ic.channels[i].ppcm_data;
                if (ppcm[i] != 0)
                {
                    delta[i] /= 2;
                }
            }

            for (j = 0; j < samples; j++)
            {
                dataL = dataR = 0;

                for (i = 0; i < 4; i++)
                {
                    /* see if the voice is on */
                    if (play[i] != 0)
                    {
                        /* see if we're done */
                        if ((pos[i] >> BASE_SHIFT) >= end[i])
                        {
                            ppcm_data[i] = 0;
                            if (loop[i] != 0)
                            {
                                pos[i] = 0;
                            }
                            else
                            {
                                play[i] = 0;
                                continue;
                            }
                        }

                        if (ppcm[i] != 0)
                        { /* Packed PCM */
                          /* we only update the signal if we're starting or a real sound sample has gone by */
                          /* this is all due to the dynamic sample rate conversion */
                            if (pos[i] == 0 || ((pos[i] ^ (pos[i] - delta[i])) & 0x8000) == 0x8000)

                            {
                                Int32 newdata;
                                if ((pos[i] & 0x8000) != 0)
                                {
                                    //newdata = ((rom[i][pos[i] >> BASE_SHIFT]) >> 4) & 0x0f; /*high nybble*/
                                    newdata = ((ic.rom[ptrRom[i] + (pos[i] >> BASE_SHIFT)]) >> 4) & 0x0f; /*high nybble*/
                                }
                                else
                                {
                                    //newdata = ((rom[i][pos[i] >> BASE_SHIFT])) & 0x0f; /*low nybble*/
                                    newdata = ((ic.rom[ptrRom[i] + (pos[i] >> BASE_SHIFT)])) & 0x0f; /*low nybble*/
                                }

                                /*ppcm_data[i] = (( ( ppcm_data[i] * 62 ) >> 6 ) + dpcmcnv[newdata]);
                                 *
                                 * if ( ppcm_data[i] > 127 )
                                 *  ppcm_data[i] = 127;
                                 * else
                                 *  if ( ppcm_data[i] < -128 )
                                 *      ppcm_data[i] = -128;*/
                                ppcm_data[i] += dpcmcnv[newdata];
                            }



                            d = ppcm_data[i];

                            pos[i] += delta[i];
                        }
                        else
                        { /* PCM */
                            //d = rom[i][pos[i] >> BASE_SHIFT];
                            d = (sbyte)ic.rom[ptrRom[i] + (pos[i] >> BASE_SHIFT)];

                            pos[i] += delta[i];
                        }

                        if ((ic.mode & 2) != 0)
                        {
                            dataL += (d * lvol[i]) >> 2;
                            dataR += (d * rvol[i]) >> 2;
                        }
                    }
                }

                outputs[1][j] = limit(dataL, MAXOUT, MINOUT);
                outputs[0][j] = limit(dataR, MAXOUT, MINOUT);
            }

            /* update the regs now */
            for (i = 0; i < 4; i++)
            {
                if (ic.channels[i].Muted != 0)
                {
                    continue;
                }
                ic.channels[i].pos       = pos[i];
                ic.channels[i].play      = play[i];
                ic.channels[i].ppcm_data = ppcm_data[i];
            }
        }