Пример #1
0
        private void partInit()
        {
            foreach (clsChip chip in chips)
            {

                chip.use = false;
                chip.lstPartWork = new List<partWork>();

                for (int i = 0; i < chip.ChMax; i++)
                {
                    partWork pw = new partWork();
                    pw.chip = chip;
                    pw.isSecondary = (chip.ChipID == 1);
                    pw.ch = i;// + 1;
                    if (partData.ContainsKey(chip.Ch[i].Name))
                    {
                        pw.pData = partData[chip.Ch[i].Name];
                    }
                    pw.aData = aliesData;
                    pw.setPos(0);
                    pw.Type = chip.Ch[i].Type;
                    pw.slots = 0;
                    pw.volume = 32767;

                    if (chip is YM2612)
                    {
                        pw.slots = (byte)(((pw.Type == enmChannelType.FMOPN || pw.Type == enmChannelType.FMPCM) || i == 2) ? 0xf : 0x0);
                        pw.volume = 127;
                        pw.MaxVolume = 127;
                        pw.port0 = (byte)(0x2 | (pw.isSecondary ? 0xa0 : 0x50));
                        pw.port1 = (byte)(0x3 | (pw.isSecondary ? 0xa0 : 0x50));
                    }
                    else if (chip is SN76489)
                    {
                        pw.MaxVolume = 15;
                        pw.volume = pw.MaxVolume;
                        pw.port0 = 0x50;
                    }
                    else if (chip is RF5C164)
                    {
                        pw.MaxVolume = 255;
                        pw.volume = pw.MaxVolume;
                        pw.port0 = 0xb1;
                    }
                    else if (chip is YM2610B)
                    {
                        pw.slots = (byte)((pw.Type == enmChannelType.FMOPN || i == 2) ? 0xf : 0x0);
                        pw.volume = 127;
                        pw.MaxVolume = 127;
                        if (pw.Type == enmChannelType.SSG)
                        {
                            //pw.volume = 32767;
                            pw.MaxVolume = 15;
                            pw.volume = pw.MaxVolume;
                        }
                        else if (pw.Type == enmChannelType.ADPCMA)
                        {
                            //pw.volume = 32767;
                            pw.MaxVolume = 31;//5bit
                            pw.volume = pw.MaxVolume;
                        }
                        else if (pw.Type == enmChannelType.ADPCMB)
                        {
                            //pw.volume = 32767;
                            pw.MaxVolume = 255;
                            pw.volume = pw.MaxVolume;
                        }
                        pw.port0 = (byte)(0x8 | (pw.isSecondary ? 0xa0 : 0x50));
                        pw.port1 = (byte)(0x9 | (pw.isSecondary ? 0xa0 : 0x50));
                    }

                    pw.PartName = chip.Ch[i].Name;
                    pw.waitKeyOnCounter = -1;
                    pw.waitCounter = 0;
                    pw.freq = -1;

                    pw.dataEnd = false;
                    if (pw.pData == null || pw.pData.Count < 1)
                    {
                        pw.dataEnd = true;
                    }
                    else
                    {
                        chip.use = true;
                    }

                    chip.lstPartWork.Add(pw);

                }
            }
        }
Пример #2
0
 private static void procBend(partWork pw)
 {
     //bend処理
     if (pw.bendWaitCounter == 0)
     {
         if (pw.bendList.Count > 0)
         {
             Tuple<int, int> bp = pw.bendList.Pop();
             pw.bendFnum = bp.Item1;
             pw.bendWaitCounter = bp.Item2;
         }
         else
         {
             pw.bendWaitCounter = -1;
         }
     }
 }
Пример #3
0
 private void cmdDetune(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正なディチューン'D'が指定されています。", lineNumber);
         n = 0;
     }
     n = checkRange(n, -127, 127);
     pw.detune = n;
 }
Пример #4
0
        private void setSsgFNum(partWork pw)
        {
            int f = getSsgFNum(pw.octaveNow, pw.noteCmd, pw.shift + pw.keyShift);//
            if (pw.bendWaitCounter != -1)
            {
                f = pw.bendFnum;
            }
            f = f + pw.detune;
            for (int lfo = 0; lfo < 4; lfo++)
            {
                if (!pw.lfo[lfo].sw)
                {
                    continue;
                }
                if (pw.lfo[lfo].type != eLfoType.Vibrato)
                {
                    continue;
                }
                f += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
            }

            f = checkRange(f, 0, 0xfff);
            if (pw.freq == f) return;

            pw.freq = f;

            byte data = 0;

            data = (byte)(f & 0xff);
            outFmAdrPort(pw.port0, (byte)(0 + (pw.ch - 9) * 2), data);

            data = (byte)((f & 0xf00) >> 8);
            outFmAdrPort(pw.port0, (byte)(1 + (pw.ch - 9) * 2), data);
        }
Пример #5
0
        private void setYM2610BADPCMAAddress(partWork pw, int startAdr, int endAdr)
        {
            if (pw.pcmStartAddress != startAdr)
            {
                outFmAdrPort(pw.port1, (byte)(0x10 + (pw.ch - 12)), (byte)((startAdr >> 8) & 0xff));
                outFmAdrPort(pw.port1, (byte)(0x18 + (pw.ch - 12)), (byte)((startAdr >> 16) & 0xff));
                pw.pcmStartAddress = startAdr;
            }

            if (pw.pcmEndAddress != endAdr)
            {
                outFmAdrPort(pw.port1, (byte)(0x20 + (pw.ch - 12)), (byte)(((endAdr - 0x100) >> 8) & 0xff));
                outFmAdrPort(pw.port1, (byte)(0x28 + (pw.ch - 12)), (byte)(((endAdr - 0x100) >> 16) & 0xff));
                pw.pcmEndAddress = endAdr;
            }
        }
Пример #6
0
 private void setRf5c164LoopAddress(partWork pw, int adr)
 {
     if (pw.pcmLoopAddress != adr)
     {
         byte data = (byte)((adr >> 8) & 0xff);
         outRf5c164Port(pw.isSecondary, 0x5, data);
         data = (byte)(adr & 0xff);
         outRf5c164Port(pw.isSecondary, 0x4, data);
         pw.pcmLoopAddress = adr;
     }
 }
Пример #7
0
 private void setRf5c164SampleStartAddress(partWork pw, int adr)
 {
     if (pw.pcmStartAddress != adr)
     {
         byte data = (byte)((adr >> 8) & 0xff);
         outRf5c164Port(pw.isSecondary, 0x6, data);
         pw.pcmStartAddress = adr;
     }
 }
Пример #8
0
        private void setEnvelopeAtKeyOn(partWork pw)
        {
            if (!pw.envelopeMode)
            {
                pw.envVolume = 0;
                pw.envIndex = -1;
                return;
            }

            pw.envIndex = 0;
            pw.envCounter = 0;
            int maxValue = pw.MaxVolume;// (pw.envelope[8] == (int)enmChipType.RF5C164) ? 255 : 15;

            while (pw.envCounter == 0 && pw.envIndex != -1)
            {
                switch (pw.envIndex)
                {
                    case 0: // AR phase
                        pw.envCounter = pw.envelope[2];
                        if (pw.envelope[2] > 0 && pw.envelope[1] < maxValue)
                        {
                            pw.envVolume = pw.envelope[1];
                        }
                        else
                        {
                            pw.envVolume = maxValue;
                            pw.envIndex++;
                        }
                        break;
                    case 1: // DR phase
                        pw.envCounter = pw.envelope[3];
                        if (pw.envelope[3] > 0 && pw.envelope[4] < maxValue)
                        {
                            pw.envVolume = maxValue;
                        }
                        else
                        {
                            pw.envVolume = pw.envelope[4];
                            pw.envIndex++;
                        }
                        break;
                    case 2: // SR phase
                        pw.envCounter = pw.envelope[5];
                        if (pw.envelope[5] > 0 && pw.envelope[4] != 0)
                        {
                            pw.envVolume = pw.envelope[4];
                        }
                        else
                        {
                            pw.envVolume = 0;
                            pw.envIndex = -1;
                        }
                        break;
                }
            }
        }
Пример #9
0
        private int setEnvelopParamFromInstrument(partWork pw)
        {
            int n;
            if (!pw.getNum(out n))
            {
                msgBox.setErrMsg("不正なエンベロープ番号が指定されています。", lineNumber);
                n = 0;
            }
            n = checkRange(n, 0, 255);
            if (!instENV.ContainsKey(n))
            {
                msgBox.setErrMsg(string.Format("エンベロープ定義に指定された音色番号({0})が存在しません。", n), lineNumber);
            }
            else
            {
                if (pw.envInstrument != n)
                {
                    pw.envInstrument = n;
                    pw.envIndex = -1;
                    pw.envCounter = -1;
                    for (int i = 0; i < instENV[n].Length; i++)
                    {
                        pw.envelope[i] = instENV[n][i];
                    }
                }
            }

            return n;
        }
Пример #10
0
 private void setAdpcmBPan(partWork pw, int pan)
 {
     if (pw.pan != pan)
     {
         outFmAdrPort(pw.port0, 0x11, (byte)((pan & 0x3) << 6));
         pw.pan = pan;
     }
 }
Пример #11
0
        private void setAdpcmBVolume(partWork pw)
        {
            int vol = pw.volume;
            if (pw.envelopeMode)
            {
                vol = 0;
                if (pw.envIndex != -1)
                {
                    vol = pw.volume - (0xff - pw.envVolume);
                }
            }
            vol = checkRange(vol, 0, 0xff);

            if (pw.beforeVolume != vol)
            {
                outFmAdrPort(pw.port0, 0x1b, (byte)vol);
                pw.beforeVolume = pw.volume;
            }
        }
Пример #12
0
        private void procLfo(partWork cpw)
        {
            //lfo処理
            for (int lfo = 0; lfo < 4; lfo++)
            {
                clsLfo pl = cpw.lfo[lfo];

                if (!pl.sw)
                {
                    continue;
                }
                if (pl.waitCounter > 0)//== -1)
                {
                    continue;
                }

                if (pl.type == eLfoType.Hardware)
                {
                    if (cpw.chip is YM2612)
                    {
                        cpw.ams = pl.param[3];
                        cpw.fms = pl.param[2];
                        outOPNSetPanAMSFMS(cpw, cpw.pan, cpw.ams, cpw.fms);
                        cpw.chip.lstPartWork[0].hardLfoSw = true;
                        cpw.chip.lstPartWork[0].hardLfoNum = pl.param[1];
                        outOPNSetHardLfo(cpw, cpw.hardLfoSw, cpw.hardLfoNum);
                        pl.waitCounter = -1;
                    }
                    continue;
                }

                switch (pl.param[4])
                {
                    case 0: //三角
                        pl.value += Math.Abs(pl.param[2]) * pl.direction;
                        pl.waitCounter = pl.param[1];
                        if ((pl.direction > 0 && pl.value >= pl.param[3]) || (pl.direction < 0 && pl.value <= -pl.param[3]))
                        {
                            pl.value = pl.param[3] * pl.direction;
                            pl.direction = -pl.direction;
                        }
                        break;
                    case 1: //のこぎり
                        pl.value += Math.Abs(pl.param[2]) * pl.direction;
                        pl.waitCounter = pl.param[1];
                        if ((pl.direction > 0 && pl.value >= pl.param[3]) || (pl.direction < 0 && pl.value <= -pl.param[3]))
                        {
                            pl.value = -pl.param[3] * pl.direction;
                        }
                        break;
                    case 2: //矩形
                        pl.value = pl.param[3] * pl.direction;
                        pl.waitCounter = pl.param[1];
                        pl.direction = -pl.direction;
                        break;
                    case 3: //ワンショット
                        pl.value += Math.Abs(pl.param[2]) * pl.direction;
                        pl.waitCounter = pl.param[1];
                        if ((pl.direction > 0 && pl.value >= pl.param[3]) || (pl.direction < 0 && pl.value <= -pl.param[3]))
                        {
                            pl.waitCounter = -1;
                        }
                        break;
                    case 4: //ランダム
                        pl.value = rnd.Next(-pl.param[3], pl.param[3]);
                        pl.waitCounter = pl.param[1];
                        break;
                }

            }
        }
Пример #13
0
        private void procKeyOff(partWork pw)
        {
            if (pw.waitKeyOnCounter == 0)
            {
                if (pw.chip is YM2610B)
                {
                    if (!pw.tie)
                    {
                        if (pw.ch < 9) outFmKeyOff(pw);
                        else if (pw.Type == enmChannelType.SSG)
                        {
                            if (!pw.envelopeMode)
                            {
                                outSsgKeyOff(pw);
                            }
                            else
                            {
                                if (pw.envIndex != -1)
                                {
                                    pw.envIndex = 3;//RR phase
                                    pw.envCounter = 0;
                                }
                            }
                        }
                        else if (pw.Type == enmChannelType.ADPCMA)
                        {
                            pw.keyOn = false;
                            pw.keyOff = true;
                            //((YM2610B)pw.chip).adpcmA_KeyOff |= (byte)(1 << (pw.ch - 12));
                        }
                        else if (pw.Type == enmChannelType.ADPCMB)
                        {
                            if (!pw.envelopeMode)
                            {
                                outAdpcmBKeyOff(pw);
                            }
                            else
                            {
                                if (pw.envIndex != -1)
                                {
                                    pw.envIndex = 3;//RR phase
                                    pw.envCounter = 0;
                                }
                            }
                        }
                    }
                }
                else if (pw.chip is YM2612)
                {
                    if (!pw.tie)
                    {
                        outFmKeyOff(pw);
                    }
                }
                else if (pw.chip is SN76489)
                {
                    if (!pw.envelopeMode)
                    {
                        if (!pw.tie) outPsgKeyOff(pw);
                    }
                    else
                    {
                        if (pw.envIndex != -1)
                        {
                            if (!pw.tie)
                            {
                                pw.envIndex = 3;//RR phase
                                pw.envCounter = 0;
                            }
                        }
                    }
                }
                else
                {
                    if (!pw.envelopeMode)
                    {
                        if (!pw.tie) outRf5c164KeyOff(pw);
                    }
                    else
                    {
                        if (pw.envIndex != -1)
                        {
                            if (!pw.tie)
                            {
                                pw.envIndex = 3;//RR phase
                                pw.envCounter = 0;
                            }
                        }
                    }
                }

                //次回に引き継ぎリセット
                pw.beforeTie = pw.tie;
                pw.tie = false;

                //ゲートタイムカウンターをリセット
                pw.waitKeyOnCounter = -1;
            }
        }
Пример #14
0
        private void procEnvelope(partWork pw)
        {
            //Envelope処理
            if (
                (pw.chip is YM2610B && (pw.Type == enmChannelType.SSG || pw.Type == enmChannelType.ADPCMA || pw.Type == enmChannelType.ADPCMB))
                || pw.chip is SN76489
                || pw.chip is RF5C164
                )
            {
                envelope(pw);
            }

            if ((pw.chip is YM2610B && pw.ch < 6) || (pw.chip is YM2612))
            {
                setFmFNum(pw);
                setFmVolume(pw);
            }
            else if (pw.chip is YM2610B && pw.Type == enmChannelType.SSG)
            {
                setSsgFNum(pw);
                setSsgVolume(pw);
            }
            else if (pw.chip is YM2610B && pw.Type == enmChannelType.ADPCMB)
            {
                setAdpcmBFNum(pw);
                setAdpcmBVolume(pw);
            }
            else if (pw.chip is SN76489)
            {
                if (pw.waitKeyOnCounter > 0 || pw.envIndex != -1)
                {
                    setPsgFNum(pw);
                    setPsgVolume(pw);
                }
            }
            else if (pw.chip is RF5C164)
            {
                if (pw.waitKeyOnCounter > 0 || pw.envIndex != -1)
                {
                    setRf5c164FNum(pw);
                    setRf5c164Volume(pw);
                }
            }
        }
Пример #15
0
 private void setRf5c164Envelope(partWork pw, int volume)
 {
     if (pw.rf5c164Envelope != volume)
     {
         setRf5c164CurrentChannel(pw);
         byte data = (byte)(volume & 0xff);
         outRf5c164Port(pw.isSecondary, 0x0, data);
         pw.rf5c164Envelope = volume;
     }
 }
Пример #16
0
        private void setFmFNum(partWork pw)
        {
            int[] ftbl = (pw.chip is YM2612) ? OPN_FNumTbl_7670454 : OPN_FNumTbl_8000000;

            int f = getFmFNum(ftbl, pw.octaveNow, pw.noteCmd, pw.shift + pw.keyShift);//
            if (pw.bendWaitCounter != -1)
            {
                f = pw.bendFnum;
            }
            int o = (f & 0xf000) / 0x1000;
            f &= 0xfff;

            f = f + pw.detune;
            for (int lfo = 0; lfo < 4; lfo++)
            {
                if (!pw.lfo[lfo].sw)
                {
                    continue;
                }
                if (pw.lfo[lfo].type != eLfoType.Vibrato)
                {
                    continue;
                }
                f += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
            }
            while (f < ftbl[0])
            {
                if (o == 1)
                {
                    break;
                }
                o--;
                f = ftbl[0] * 2 - (ftbl[0] - f);
            }
            while (f >= ftbl[0] * 2)
            {
                if (o == 8)
                {
                    break;
                }
                o++;
                f = f - ftbl[0] * 2 + ftbl[0];
            }
            f = checkRange(f, 0, 0x7ff);

            outFmSetFnum(pw, o, f);
        }
Пример #17
0
        private void setRf5c164FNum(partWork pw)
        {
            int f = getRf5c164PcmNote(pw.octaveNow, pw.noteCmd, pw.keyShift + pw.shift);//

            if (pw.bendWaitCounter != -1)
            {
                f = pw.bendFnum;
            }
            f = f + pw.detune;
            for (int lfo = 0; lfo < 4; lfo++)
            {
                if (!pw.lfo[lfo].sw)
                {
                    continue;
                }
                if (pw.lfo[lfo].type != eLfoType.Vibrato)
                {
                    continue;
                }
                f += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
            }

            f = checkRange(f, 0, 0xffff);
            pw.freq = f;

            setRf5c164CurrentChannel(pw);

            //Address increment 再生スピードをセット
            setRf5c164AddressIncrement(pw, f);
        }
Пример #18
0
        private void setFmVolume(partWork pw)
        {
            int vol = pw.volume;

            for (int lfo = 0; lfo < 4; lfo++)
            {
                if (!pw.lfo[lfo].sw)
                {
                    continue;
                }
                if (pw.lfo[lfo].type != eLfoType.Tremolo)
                {
                    continue;
                }
                vol += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
            }

            if (pw.beforeVolume != vol)
            {
                if (instFM.ContainsKey(pw.instrument))
                {
                    outFmSetVolume(pw, vol, pw.instrument);
                    pw.beforeVolume = vol;
                }
            }
        }
Пример #19
0
 private void setRf5c164Pan(partWork pw, int pan)
 {
     if (pw.rf5c164Pan != pan)
     {
         setRf5c164CurrentChannel(pw);
         byte data = (byte)(pan & 0xff);
         outRf5c164Port(pw.isSecondary, 0x1, data);
         pw.rf5c164Pan = pan;
     }
 }
Пример #20
0
        private void setLfoAtKeyOn(partWork pw)
        {
            for (int lfo = 0; lfo < 4; lfo++)
            {
                clsLfo pl = pw.lfo[lfo];
                if (!pl.sw)
                {
                    continue;
                }
                if (pl.type == eLfoType.Hardware)
                {
                    if (pw.chip is YM2612)
                    {
                        if (pl.param[4] == 1)
                        {
                            outOPNSetHardLfo(pw, false, pl.param[1]);
                            pl.waitCounter = pl.param[0];
                        }
                    }
                    continue;
                }
                if (pl.param[5] != 1)
                {
                    continue;
                }

                pl.isEnd = false;
                pl.value = (pl.param[0] == 0) ? pl.param[6] : 0;//ディレイ中は振幅補正は適用されない
                pl.waitCounter = pl.param[0];
                pl.direction = pl.param[2] < 0 ? -1 : 1;
                if (pl.type == eLfoType.Vibrato)
                {
                    if ((pw.chip is YM2610B) || (pw.chip is YM2612))
                    {
                        setFmFNum(pw);
                    }
                }
                if (pl.type == eLfoType.Tremolo)
                {
                    if ((pw.chip is YM2610B) || (pw.chip is YM2612))
                    {
                        pw.beforeVolume = -1;
                        setFmVolume(pw);
                    }
                }
            }
        }
Пример #21
0
        private void setRf5c164Volume(partWork pw)
        {
            int vol = pw.volume;

            if (pw.envelopeMode)
            {
                vol = 0;
                if (pw.envIndex != -1)
                {
                    vol = pw.envVolume - (255 - pw.volume);
                }
            }

            for (int lfo = 0; lfo < 4; lfo++)
            {
                if (!pw.lfo[lfo].sw)
                {
                    continue;
                }
                if (pw.lfo[lfo].type != eLfoType.Tremolo)
                {
                    continue;
                }
                vol += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
            }

            vol = checkRange(vol, 0, 255);

            if (pw.beforeVolume != vol)
            {
                setRf5c164Envelope(pw, vol);
                pw.beforeVolume = vol;
            }
        }
Пример #22
0
        private void setPsgFNum(partWork pw)
        {
            if (pw.Type != enmChannelType.DCSGNOISE)
            {
                int f = getPsgFNum(pw.octaveNow, pw.noteCmd, pw.shift + pw.keyShift);//
                if (pw.bendWaitCounter != -1)
                {
                    f = pw.bendFnum;
                }
                f = f + pw.detune;
                for (int lfo = 0; lfo < 4; lfo++)
                {
                    if (!pw.lfo[lfo].sw)
                    {
                        continue;
                    }
                    if (pw.lfo[lfo].type != eLfoType.Vibrato)
                    {
                        continue;
                    }
                    f += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
                }

                f = checkRange(f, 0, 0x3ff);
                if (pw.freq == f) return;

                pw.freq = f;

                byte data = 0;

                data = (byte)(0x80 + (pw.ch << 5) + (f & 0xf));
                outPsgPort(pw.isSecondary, data);

                data = (byte)((f & 0x3f0) >> 4);
                outPsgPort(pw.isSecondary, data);
            }
            else
            {
                int f = pw.noise;
                byte data = (byte)(0xe0 + (f & 0x7));
                pw.freq = 0x40 + (f & 7);
            }
        }
Пример #23
0
        private void setSsgVolume(partWork pw)
        {
            byte pch = (byte)(pw.ch - 9);

            int vol = pw.volume;
            if (pw.envelopeMode)
            {
                vol = 0;
                if (pw.envIndex != -1)
                {
                    vol = pw.volume - (15 - pw.envVolume);
                }
            }
            vol = checkRange(vol, 0, 15);

            if (pw.beforeVolume != vol)
            {
                outFmAdrPort(pw.port0, (byte)(0x08 + pch), (byte)vol);
                pw.beforeVolume = pw.volume;
            }
        }
Пример #24
0
        private void setPsgVolume(partWork pw)
        {
            byte data = 0;

            int vol = pw.volume;

            if (pw.envelopeMode)
            {
                vol = 0;
                if (pw.envIndex != -1)
                {
                    vol = pw.envVolume - (15 - pw.volume);
                }
            }

            for (int lfo = 0; lfo < 4; lfo++)
            {
                if (!pw.lfo[lfo].sw) continue;
                if (pw.lfo[lfo].type != eLfoType.Tremolo) continue;

                vol += pw.lfo[lfo].value + pw.lfo[lfo].param[6];
            }

            vol = checkRange(vol, 0, 15);

            if (pw.beforeVolume != vol)
            {
                data = (byte)(0x80 + (pw.ch << 5) + 0x10 + (15 - vol));
                outPsgPort(pw.isSecondary, data);
                pw.beforeVolume = vol;
            }
        }
Пример #25
0
        private void setYM2610BADPCMBAddress(partWork pw, int startAdr, int endAdr)
        {
            if (pw.pcmStartAddress != startAdr)
            {
                outFmAdrPort(pw.port0, 0x12, (byte)((startAdr >> 8) & 0xff));
                outFmAdrPort(pw.port0, 0x13, (byte)((startAdr >> 16) & 0xff));
                pw.pcmStartAddress = startAdr;
            }

            if (pw.pcmEndAddress != endAdr)
            {
                outFmAdrPort(pw.port0, 0x14, (byte)(((endAdr - 0x100) >> 8) & 0xff));
                outFmAdrPort(pw.port0, 0x15, (byte)(((endAdr - 0x100) >> 16) & 0xff));
                pw.pcmEndAddress = endAdr;
            }

            //outFmAdrPort(pw.port1, 0x01, 0x3f);
            //outFmAdrPort(pw.port1, 0x08, 0xdf);
            //outFmAdrPort(pw.port1, 0x00, 0x01);
        }
Пример #26
0
 private void setRf5c164AddressIncrement(partWork pw, int f)
 {
     if (pw.rf5c164AddressIncrement != f)
     {
         byte data = (byte)(f & 0xff);
         outRf5c164Port(pw.isSecondary, 0x2, data);
         data = (byte)((f >> 8) & 0xff);
         outRf5c164Port(pw.isSecondary, 0x3, data);
         pw.rf5c164AddressIncrement = f;
     }
 }
Пример #27
0
 private void cmdClockLength(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正な音長が指定されています。", lineNumber);
         n = 10;
     }
     n = checkRange(n, 1, 65535);
     pw.length = n;
 }
Пример #28
0
        private void setRf5c164CurrentChannel(partWork pw)
        {
            byte pch = (byte)pw.ch;
            bool isSecondary = pw.isSecondary;
            int chipID = pw.chip.ChipID;

            if (rf5c164[chipID].CurrentChannel != pch)
            {
                byte data = (byte)(0xc0 + pch);
                outRf5c164Port(isSecondary, 0x7, data);
                rf5c164[chipID].CurrentChannel = pch;
            }
        }
Пример #29
0
        private void cmdEnvelope(partWork pw)
        {
            int n = -1;
            if (
                ((pw.chip is YM2610B) && (pw.Type == enmChannelType.SSG || pw.Type == enmChannelType.FMOPNex))
                || ((pw.chip is YM2612) && (pw.Type == enmChannelType.FMPCM || (pw.Type == enmChannelType.FMOPNex)))
                || (pw.chip is SN76489)
                || (pw.chip is RF5C164)
                )
            {
                pw.incPos();
                switch (pw.getChar())
                {
                    case 'O':
                        pw.incPos();
                        if (
                            ((pw.chip is YM2610B) && pw.Type == enmChannelType.FMOPNex)
                            || pw.chip is YM2612
                            )
                        {
                            switch (pw.getChar())
                            {
                                case 'N':
                                    pw.incPos();
                                    pw.Ch3SpecialMode = true;
                                    outOPNSetCh3SpecialMode(pw, true);
                                    break;
                                case 'F':
                                    pw.incPos();
                                    pw.Ch3SpecialMode = false;
                                    outOPNSetCh3SpecialMode(pw, false);
                                    break;
                                default:
                                    msgBox.setErrMsg(string.Format("未知のコマンド(EO{0})が指定されました。", pw.getChar()), lineNumber);
                                    pw.incPos();
                                    break;
                            }
                        }
                        else
                        {
                            switch (pw.getChar())
                            {
                                case 'N':
                                    pw.incPos();
                                    pw.envelopeMode = true;
                                    break;
                                case 'F':
                                    pw.incPos();
                                    pw.envelopeMode = false;
                                    break;
                                default:
                                    msgBox.setErrMsg(string.Format("未知のコマンド(EO{0})が指定されました。", pw.getChar()), lineNumber);
                                    pw.incPos();
                                    break;
                            }
                        }
                        break;
                    case 'X':
                        char c = pw.getChar();
                        if (
                            ((pw.chip is YM2610B) && pw.Type == enmChannelType.FMOPNex)
                            || pw.chip is YM2612
                            )
                        {
                            pw.incPos();
                            if (!pw.getNum(out n))
                            {
                                msgBox.setErrMsg("不正なスロット指定'EX'が指定されています。", lineNumber);
                                n = 0;
                            }
                            byte res = 0;
                            while (n % 10 != 0)
                            {
                                if (n % 10 > 0 && n % 10 < 5)
                                {
                                    res += (byte)(1 << (n % 10 - 1));
                                }
                                else
                                {
                                    msgBox.setErrMsg(string.Format("未知のコマンド(EX{0})が指定されました。", n), lineNumber);
                                    break;
                                }
                                n /= 10;
                            }
                            if (res != 0)
                            {
                                pw.slots = res;
                            }
                        }
                        else
                        {
                            msgBox.setErrMsg("未知のコマンド(EX)が指定されました。", lineNumber);
                        }
                        break;
                    default:
                        if (pw.Type == enmChannelType.FMOPNex)
                        {
                            int[] s = new int[] { 0, 0, 0, 0 };

                            for (int i = 0; i < 4; i++)
                            {
                                if (pw.getNum(out n))
                                {
                                    s[i] = n;
                                }
                                else
                                {
                                    msgBox.setErrMsg("Eコマンドの解析に失敗しました。", lineNumber);
                                    break;
                                }
                                if (i == 3) break;
                                pw.incPos();
                            }
                            pw.slotDetune = s;
                            break;
                        }
                        else
                        {
                            msgBox.setErrMsg(string.Format("未知のコマンド(E{0})が指定されました。", pw.getChar()), lineNumber);
                            pw.incPos();
                        }
                        break;
                }
            }
            else
            {
                msgBox.setWrnMsg("このパートは効果音モードに対応したチャンネルが指定されていないため、Eコマンドは無視されます。", lineNumber);
                pw.incPos();
            }
        }
Пример #30
0
 private void outYM2612SetCh6PCMMode(partWork pw, bool sw)
 {
     dat.Add(pw.port0);
     dat.Add(0x2b);
     dat.Add((byte)((sw ? 0x80 : 0)));
 }