Exemple #1
0
 private static void k054539_keyoff(k054539_state info, int channel)
 {
     if (k054539_regupdate(info) == 0)
     {
         info.regs[0x22c] &= (byte)(~(1 << channel));
     }
 }
Exemple #2
0
        private void device_reset_k054539(byte ChipID)
        {
            k054539_state info = K054539Data[ChipID];

            for (int i = 0; i < info.regs.Length; i++)
            {
                info.regs[i] = 0;
            }
            for (int i = 0; i < info.k054539_posreg_latch.Length; i++)
            {
                for (int j = 0; j < info.k054539_posreg_latch[i].Length; j++)
                {
                    info.k054539_posreg_latch[i][j] = 0;
                }
            }
            //info->k054539_flags |= K054539_UPDATE_AT_KEYON;

            info.reverb_pos = 0;
            info.cur_ptr    = 0;
            for (int i = 0; i < 0x4000; i++)
            {
                info.ram[i] = 0;
            }

            return;
        }
Exemple #3
0
        //READ8_DEVICE_HANDLER( k054539_r )
        public byte k054539_r(byte ChipID, int offset)
        {
            //k054539_state *info = get_safe_token(device);
            k054539_state info = K054539Data[ChipID];

            switch (offset)
            {
            case 0x22d:
                if ((info.regs[0x22f] & 0x10) != 0)
                {
                    byte res = info.cur_zone[info.ptrCur_zone + info.cur_ptr];
                    info.cur_ptr++;
                    if (info.cur_ptr == info.cur_limit)
                    {
                        info.cur_ptr = 0;
                    }
                    return(res);
                }
                else
                {
                    return(0);
                }

            case 0x22c:
                break;

            default:
                //LOG(("K054539 read %03x\n", offset));
                break;
            }
            return(info.regs[offset]);
        }
Exemple #4
0
        /*INLINE k054539_state *get_safe_token(device_t *device)
         * {
         *  assert(device != NULL);
         *  assert(device->type() == K054539);
         *  return (k054539_state *)downcast<legacy_device_base *>(device)->token();
         * }*/

        //*

        //void k054539_init_flags(device_t *device, int flags)
        public void k054539_init_flags(byte ChipID, int flags)
        {
            //k054539_state *info = get_safe_token(device);
            k054539_state info = K054539Data[ChipID];

            info.k054539_flags = flags;
        }
Exemple #5
0
        private static void reset_zones(k054539_state info)
        {
            int data = info.regs[0x22e];

            info.cur_zone    = data == 0x80 ? info.ram : info.rom;
            info.ptrCur_zone = data == 0x80 ? 0 : (0x20000 * data);
            info.cur_limit   = data == 0x80 ? 0x4000 : 0x20000;
        }
Exemple #6
0
        private void device_stop_k054539(byte ChipID)
        {
            k054539_state info = K054539Data[ChipID];

            info.rom = null;
            info.ram = null;

            return;
        }
Exemple #7
0
        //void k054539_set_gain(device_t *device, int channel, double gain)
        public void k054539_set_gain(byte ChipID, int channel, double gain)
        {
            //k054539_state *info = get_safe_token(device);
            k054539_state info = K054539Data[ChipID];

            if (gain >= 0)
            {
                info.k054539_gain[channel] = gain;
            }
        }
Exemple #8
0
        public void k054539_set_mute_mask(byte ChipID, uint MuteMask)
        {
            k054539_state info = K054539Data[ChipID];
            byte          CurChn;

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

            return;
        }
Exemple #9
0
        /*static TIMER_CALLBACK( k054539_irq )
         * {
         *  k054539_state *info = (k054539_state *)ptr;
         *  if(info->regs[0x22f] & 0x20)
         *      info->intf->irq(info->device);
         * }*/

        //static void k054539_init_chip(device_t *device, k054539_state *info)
        private static int k054539_init_chip(k054539_state info, int clock)
        {
            //int i;

            if (clock < 1000000) // if < 1 MHz, then it's the sample rate, not the clock
            {
                clock *= 384;    // (for backwards compatibility with old VGM logs)
            }
            info.clock = clock;
            // most of these are done in device_reset
            //	memset(info->regs, 0, sizeof(info->regs));
            //	memset(info->k054539_posreg_latch, 0, sizeof(info->k054539_posreg_latch)); //*
            info.k054539_flags |= K054539_UPDATE_AT_KEYON; //* make it default until proven otherwise

            info.ram = new byte[0x4000];
            //	info->reverb_pos = 0;
            //	info->cur_ptr = 0;
            //	memset(info->ram, 0, 0x4000);

            /*const memory_region *region = (info->intf->rgnoverride != NULL) ? device->machine().region(info->intf->rgnoverride) : device->region();
             * info->rom = *region;
             * info->rom_size = region->bytes();
             * info->rom_mask = 0xffffffffU;
             * for(i=0; i<32; i++)
             *  if((1U<<i) >= info->rom_size) {
             *      info->rom_mask = (1U<<i) - 1;
             *      break;
             *  }*/
            info.rom      = null;
            info.rom_size = 0;
            info.rom_mask = 0x00;

            //if(info->intf->irq)
            // One or more of the registers must be the timer period
            // And anyway, this particular frequency is probably wrong
            // 480 hz is TRUSTED by gokuparo disco stage - the looping sample doesn't line up otherwise
            //	device->machine().scheduler().timer_pulse(attotime::from_hz(480), FUNC(k054539_irq), 0, info);

            //info->stream = device->machine().sound().stream_alloc(*device, 0, 2, device->clock() / 384, info, k054539_update);

            //device->save_item(NAME(info->regs));
            //device->save_pointer(NAME(info->ram), 0x4000);
            //device->save_item(NAME(info->cur_ptr));

            return(info.clock / 384);
        }
Exemple #10
0
        public void k054539_write_rom2(byte ChipID, int ROMSize, int DataStart, int DataLength,
                                       byte[] ROMData, int startAdr)
        {
            k054539_state info = K054539Data[ChipID];

            if (info.rom_size != ROMSize)
            {
                byte i;

                info.rom      = new byte[ROMSize];
                info.rom_size = (uint)ROMSize;
                for (int ind = 0; ind < ROMSize; ind++)
                {
                    info.rom[ind] = 0xff;
                }

                info.rom_mask = 0xFFFFFFFF;
                for (i = 0; i < 32; i++)
                {
                    if ((1U << i) >= info.rom_size)
                    {
                        info.rom_mask = (uint)((1 << i) - 1);
                        break;
                    }
                }
            }
            if (DataStart > ROMSize)
            {
                return;
            }
            if (DataStart + DataLength > ROMSize)
            {
                DataLength = ROMSize - DataStart;
            }

            for (int j = 0; j < DataLength; j++)
            {
                info.rom[DataStart + j] = ROMData[startAdr + j];
            }

            return;
        }
Exemple #11
0
        //WRITE8_DEVICE_HANDLER( k054539_w )
        private void k054539_w(byte ChipID, int offset, byte data)
        {
            //k054539_state *info = get_safe_token(device);
            k054539_state info = K054539Data[ChipID];

            //#if 0
            //	int voice, reg;

            //	/* The K054539 has behavior like many other wavetable chips including
            //       the Ensoniq 550x and Gravis GF-1: if a voice is active, writing
            //       to it's current position is silently ignored.

            //       Dadandaan depends on this or the vocals go wrong.
            //       */
            //	if (offset < 8*0x20)
            //	{
            //		voice = offset / 0x20;
            //		reg = offset & ~0x20;

            //		if(info->regs[0x22c] & (1<<voice))
            //		{
            //			if (reg >= 0xc && reg <= 0xe)
            //				return;
            //		}
            //	}
            //#endif

            bool latch;
            int  offs, ch, pan;

            byte[] regbase;
            int    regptr;

            regbase = info.regs;
            latch   = (info.k054539_flags & K054539_UPDATE_AT_KEYON) != 0 && (regbase[0x22f] & 1) != 0;
            //Console.Write("latch = {0} \n", latch);

            if (latch && offset < 0x100)
            {
                offs = (offset & 0x1f) - 0xc;
                ch   = offset >> 5;

                if (offs >= 0 && offs <= 2)
                {
                    // latch writes to the position index registers
                    info.k054539_posreg_latch[ch][offs] = data;
                    //Console.Write("info->k054539_posreg_latch[{0}][{1}] = {2} \n", ch, offs, data);
                    return;
                }
            }

            else
            {
                switch (offset)
                {
                case 0x13f:
                    pan = (data >= 0x11 && data <= 0x1f) ? data - 0x11 : 0x18 - 0x11;
                    //if(info->intf->apan)
                    //	info->intf->apan(info->device, info->pantab[pan], info->pantab[0xe - pan]);
                    break;

                case 0x214:
                    if (latch)
                    {
                        for (ch = 0; ch < 8; ch++)
                        {
                            if ((data & (1 << ch)) != 0)
                            {
                                regptr = (ch << 5) + 0xc;

                                // update the chip at key-on
                                regbase[regptr + 0] = info.k054539_posreg_latch[ch][0];
                                regbase[regptr + 1] = info.k054539_posreg_latch[ch][1];
                                regbase[regptr + 2] = info.k054539_posreg_latch[ch][2];

                                k054539_keyon(info, ch);
                            }
                        }
                    }
                    else
                    {
                        for (ch = 0; ch < 8; ch++)
                        {
                            if ((data & (1 << ch)) != 0)
                            {
                                k054539_keyon(info, ch);
                            }
                        }
                    }
                    break;

                case 0x215:
                    for (ch = 0; ch < 8; ch++)
                    {
                        if ((data & (1 << ch)) != 0)
                        {
                            k054539_keyoff(info, ch);
                        }
                    }
                    break;

                /*case 0x227:
                 * {
                 *  attotime period = attotime::from_hz((float)(38 + data) * (clock()/384.0f/14400.0f)) / 2.0f;
                 *
                 *  m_timer->adjust(period, 0, period);
                 *
                 *  m_timer_state = 0;
                 *  m_timer_handler(m_timer_state);
                 * }*/
                //break;

                case 0x22d:
                    if (regbase[0x22e] == 0x80)
                    {
                        info.cur_zone[info.ptrCur_zone + info.cur_ptr] = data;
                    }
                    info.cur_ptr++;
                    if (info.cur_ptr == info.cur_limit)
                    {
                        info.cur_ptr = 0;
                    }
                    break;

                case 0x22e:
                    info.cur_zone =
                        data == 0x80 ? info.ram : info.rom;
                    info.ptrCur_zone =
                        data == 0x80 ? 0 : (0x20000 * data);
                    info.cur_limit = data == 0x80 ? 0x4000 : 0x20000;
                    info.cur_ptr   = 0;
                    break;

                /*case 0x22f:
                 *  if (!(data & 0x20)) // Disable timer output?
                 *  {
                 *      m_timer_state = 0;
                 *      m_timer_handler(m_timer_state);
                 *  }
                 * break;*/

                default:
                    //#if 0
                    //			if(regbase[offset] != data) {
                    //				if((offset & 0xff00) == 0) {
                    //					chanoff = offset & 0x1f;
                    //					if(chanoff < 4 || chanoff == 5 ||
                    //					   (chanoff >=8 && chanoff <= 0xa) ||
                    //					   (chanoff >= 0xc && chanoff <= 0xe))
                    //						break;
                    //				}
                    //				if(1 || ((offset >= 0x200) && (offset <= 0x210)))
                    //					break;
                    //				logerror("K054539 %03x = %02x\n", offset, data);
                    //			}
                    //#endif
                    break;
                }
            }

            regbase[offset] = data;
        }
Exemple #12
0
        //static STREAM_UPDATE( k054539_update )
        private void k054539_update(byte ChipID, int[][] outputs, int samples)
        {
            //k054539_state *info = (k054539_state *)param;
            k054539_state info    = K054539Data[ChipID];
            const double  VOL_CAP = 1.80;

            short[] dpcm = new short[16] {
                0 << 8, 1 << 8, 4 << 8, 9 << 8, 16 << 8, 25 << 8, 36 << 8, 49 << 8,
                    -64 << 8, -49 << 8, -36 << 8, -25 << 8, -16 << 8, -9 << 8, -4 << 8, -1 << 8
            };

            byte[] rbase = info.ram;//caution original INT16*
            byte[] rom;
            uint   rom_mask;
            int    i, ch;
            double lval, rval;

            byte[] base1, base2;
            int    ptrBase1, ptrBase2;

            k054539_channel[] chan;
            int    ptrChan;
            int    delta, vol, bval, pan;
            double cur_gain, lvol, rvol, rbvol;
            int    rdelta;
            uint   cur_pos;
            int    fdelta, pdelta;
            int    cur_pfrac, cur_val, cur_pval;

            for (i = 0; i < samples; i++)
            {
                outputs[0][i] = 0;
                outputs[1][i] = 0;
            }

            if ((info.regs[0x22f] & 1) == 0)
            {
                return;
            }

            rom      = info.rom;
            rom_mask = info.rom_mask;

            for (i = 0; i != samples; i++)
            {
                if ((info.k054539_flags & K054539_DISABLE_REVERB) == 0)
                {
                    //lval = rval = rbase[info.reverb_pos];
                    short val = (short)(rbase[info.reverb_pos * 2] + rbase[info.reverb_pos * 2 + 1] * 0x100);
                    lval = rval = val;
                }
                else
                {
                    lval = rval = 0;
                }
                //rbase[info.reverb_pos] = 0;
                //Console.Write("rbase[info->reverb_pos({0})] = {1} \n", info.reverb_pos, lval);
                rbase[info.reverb_pos * 2]     = 0;
                rbase[info.reverb_pos * 2 + 1] = 0;

                for (ch = 0; ch < 8; ch++)
                {
                    if (((info.regs[0x22c] & (1 << ch)) != 0) && info.Muted[ch] == 0)
                    {
                        base1    = info.regs;
                        ptrBase1 = 0x20 * ch;
                        base2    = info.regs;
                        ptrBase2 = 0x200 + 0x2 * ch;
                        chan     = info.channels;
                        ptrChan  = ch;

                        delta = base1[ptrBase1 + 0x00] | (base1[ptrBase1 + 0x01] << 8) | (base1[ptrBase1 + 0x02] << 16);

                        vol = base1[ptrBase1 + 0x03];

                        bval = vol + base1[ptrBase1 + 0x04];
                        if (bval > 255)
                        {
                            bval = 255;
                        }

                        pan = base1[ptrBase1 + 0x05];
                        // DJ Main: 81-87 right, 88 middle, 89-8f left
                        if (pan >= 0x81 && pan <= 0x8f)
                        {
                            pan -= 0x81;
                        }
                        else if (pan >= 0x11 && pan <= 0x1f)
                        {
                            pan -= 0x11;
                        }
                        else
                        {
                            pan = 0x18 - 0x11;
                        }

                        cur_gain = info.k054539_gain[ch];

                        lvol = info.voltab[vol] * info.pantab[pan] * cur_gain;
                        if (lvol > VOL_CAP)
                        {
                            lvol = VOL_CAP;
                        }

                        rvol = info.voltab[vol] * info.pantab[0xe - pan] * cur_gain;
                        if (rvol > VOL_CAP)
                        {
                            rvol = VOL_CAP;
                        }

                        rbvol = info.voltab[bval] * cur_gain / 2;
                        if (rbvol > VOL_CAP)
                        {
                            rbvol = VOL_CAP;
                        }

                        //Console.Write("ch={0} lvol={1} rvol={2}\n", ch, lvol, rvol);

                        rdelta = (base1[ptrBase1 + 6] | (base1[ptrBase1 + 7] << 8)) >> 3;
                        rdelta = (rdelta + info.reverb_pos) & 0x3fff;

                        cur_pos = (uint)((base1[ptrBase1 + 0x0c] | (base1[ptrBase1 + 0x0d] << 8) | (base1[ptrBase1 + 0x0e] << 16)) & rom_mask);

                        if ((base2[ptrBase2 + 0] & 0x20) != 0)
                        {
                            delta  = -delta;
                            fdelta = +0x10000;
                            pdelta = -1;
                        }
                        else
                        {
                            fdelta = -0x10000;
                            pdelta = +1;
                        }

                        if (cur_pos != chan[ptrChan].pos)
                        {
                            chan[ptrChan].pos = cur_pos;
                            cur_pfrac         = 0;
                            cur_val           = 0;
                            cur_pval          = 0;
                        }
                        else
                        {
                            cur_pfrac = (int)chan[ptrChan].pfrac;
                            cur_val   = chan[ptrChan].val;
                            cur_pval  = chan[ptrChan].pval;
                        }

                        switch (base2[ptrBase2 + 0] & 0xc)
                        {
                        case 0x0:
                        {         // 8bit pcm
                            cur_pfrac += delta;
                            while ((cur_pfrac & ~0xffff) != 0)
                            {
                                cur_pfrac += fdelta;
                                cur_pos   += (uint)pdelta;

                                cur_pval = cur_val;
                                cur_val  = (short)(rom[cur_pos] << 8);
                                //if(cur_val == (INT16)0x8000 && (base2[1] & 1))
                                if (rom[cur_pos] == 0x80 && (base2[ptrBase2 + 1] & 1) != 0)
                                {
                                    cur_pos = (uint)((base1[ptrBase1 + 0x08] | (base1[ptrBase1 + 0x09] << 8) | (base1[ptrBase1 + 0x0a] << 16)) & rom_mask);
                                    cur_val = (short)(rom[cur_pos] << 8);
                                }
                                //if(cur_val == (INT16)0x8000)
                                if (rom[cur_pos] == 0x80)
                                {
                                    k054539_keyoff(info, ch);
                                    cur_val = 0;
                                    break;
                                }
                            }
                            //Console.Write("ch={0} cur_pos={1} cur_val={2}\n", ch, cur_pos, cur_val);
                            //if(ch!=6) cur_val = 0;
                            break;
                        }

                        case 0x4:
                        {         // 16bit pcm lsb first
                            pdelta <<= 1;

                            cur_pfrac += delta;
                            while ((cur_pfrac & ~0xffff) != 0)
                            {
                                cur_pfrac += fdelta;
                                cur_pos   += (uint)pdelta;

                                cur_pval = cur_val;
                                cur_val  = (short)(rom[cur_pos] | rom[cur_pos + 1] << 8);
                                if (cur_val == (short)(0x8000 - 0x10000) && (base2[ptrBase2 + 1] & 1) != 0)
                                {
                                    cur_pos = (uint)((base1[ptrBase1 + 0x08] | (base1[ptrBase1 + 0x09] << 8) | (base1[ptrBase1 + 0x0a] << 16)) & rom_mask);
                                    cur_val = (short)(rom[cur_pos] | rom[cur_pos + 1] << 8);
                                }
                                if (cur_val == (short)(0x8000 - 0x10000))
                                {
                                    k054539_keyoff(info, ch);
                                    cur_val = 0;
                                    break;
                                }
                            }
                            //cur_val = 0;
                            break;
                        }

                        case 0x8:
                        {         // 4bit dpcm
                            cur_pos   <<= 1;
                            cur_pfrac <<= 1;
                            if ((cur_pfrac & 0x10000) != 0)
                            {
                                cur_pfrac &= 0xffff;
                                cur_pos   |= 1;
                            }

                            cur_pfrac += delta;
                            while ((cur_pfrac & ~0xffff) != 0)
                            {
                                cur_pfrac += fdelta;
                                cur_pos   += (uint)pdelta;

                                cur_pval = cur_val;
                                cur_val  = rom[cur_pos >> 1];
                                if (cur_val == 0x88 && (base2[ptrBase2 + 1] & 1) != 0)
                                {
                                    cur_pos = (uint)((base1[ptrBase1 + 0x08] | (base1[ptrBase1 + 0x09] << 8) | (base1[ptrBase1 + 0x0a] << 16)) & rom_mask) << 1;
                                    cur_val = rom[cur_pos >> 1];
                                }
                                if (cur_val == 0x88)
                                {
                                    k054539_keyoff(info, ch);
                                    cur_val = 0;
                                    break;
                                }
                                if ((cur_pos & 1) != 0)
                                {
                                    cur_val >>= 4;
                                }
                                else
                                {
                                    cur_val &= 15;
                                }
                                cur_val = cur_pval + dpcm[cur_val];
                                if (cur_val < -32768)
                                {
                                    cur_val = -32768;
                                }
                                else if (cur_val > 32767)
                                {
                                    cur_val = 32767;
                                }
                            }

                            cur_pfrac >>= 1;
                            if ((cur_pos & 1) != 0)
                            {
                                cur_pfrac |= 0x8000;
                            }
                            cur_pos >>= 1;
                            //cur_val = 0;
                            break;
                        }

                        default:
                            //LOG(("Unknown sample type %x for channel %d\n", base2[0] & 0xc, ch));
                            break;
                        }
                        lval += cur_val * lvol;
                        rval += cur_val * rvol;
                        //if (ch == 6)
                        //{
                        //    Console.Write("ch={0} lval={1}\n", ch, lval);
                        //}
                        int   ptr  = (rdelta + info.reverb_pos) & 0x1fff;
                        short valu = (short)(rbase[ptr * 2] + rbase[ptr * 2 + 1] * 0x100);
                        valu              += (short)(cur_val * rbvol);
                        rbase[ptr * 2]     = (byte)(valu & 0xff);
                        rbase[ptr * 2 + 1] = (byte)((valu & 0xff00) >> 8);

                        chan[ptrChan].pos   = cur_pos;
                        chan[ptrChan].pfrac = (uint)cur_pfrac;
                        chan[ptrChan].pval  = cur_pval;
                        chan[ptrChan].val   = cur_val;

                        if (k054539_regupdate(info) == 0)
                        {
                            base1[ptrBase1 + 0x0c] = (byte)(cur_pos & 0xff);
                            base1[ptrBase1 + 0x0d] = (byte)((cur_pos >> 8) & 0xff);
                            base1[ptrBase1 + 0x0e] = (byte)((cur_pos >> 16) & 0xff);
                        }
                    }
                }
                info.reverb_pos = (info.reverb_pos + 1) & 0x1fff;
                outputs[0][i]   = (int)lval;
                outputs[1][i]   = (int)rval;
                outputs[0][i] <<= 1;
                outputs[1][i] <<= 1;
                //Console.Write( "outputs[0][i] = {0}\n", outputs[0][i]);
            }
        }
Exemple #13
0
        //*

        private static int k054539_regupdate(k054539_state info)
        {
            return(info.regs[0x22f] & 0x80);
        }