Beispiel #1
0
 public static void OPL3_SlotGenerate(ref opl3_slot slot)
 {
     unsafe
     {
         slot._out = envelope_sin[slot.reg_wf]((ushort)(slot.pg_phase_out + *slot.mod), (ushort)(slot.eg_out));
     }
 }
Beispiel #2
0
 public static void OPL3_SlotWriteE0(ref opl3_slot slot, byte data)
 {
     slot.reg_wf = (byte)(data & 0x07);
     if (slot.chip.newm == 0x00)
     {
         slot.reg_wf &= 0x03;
     }
 }
Beispiel #3
0
 public static void OPL3_SlotWrite80(ref opl3_slot slot, byte data)
 {
     slot.reg_sl = (byte)((data >> 4) & 0x0f);
     if (slot.reg_sl == 0x0f)
     {
         slot.reg_sl = 0x1f;
     }
     slot.reg_rr = (byte)(data & 0x0f);
 }
Beispiel #4
0
        public static void OPL3_EnvelopeUpdateKSL(ref opl3_slot slot)
        {
            short ksl = (short)((kslrom[slot.channel.f_num >> 6] << 2) - ((0x08 - slot.channel.block) << 5));

            if (ksl < 0)
            {
                ksl = 0;
            }
            slot.eg_ksl = (byte)ksl;
        }
Beispiel #5
0
 public static void OPL3_SlotCalcFB(ref opl3_slot slot)
 {
     if (slot.channel.fb != 0x00)
     {
         slot.fbmod = (short)((slot.prout + slot._out) >> (0x09 - slot.channel.fb));
     }
     else
     {
         slot.fbmod = 0;
     }
     slot.prout = slot._out;
 }
Beispiel #6
0
        //
        // Slot
        //

        public static void OPL3_SlotWrite20(ref opl3_slot slot, byte data)
        {
            unsafe
            {
                if (((data >> 7) & 0x01) != 0)
                {
                    //slot.trem = slot.chip.tremolo;
                    slot.tremZero = false;
                }
                else
                {
                    //slot.trem = (byte)slot.chip.zeromod;
                    slot.tremZero = true;
                }
                slot.reg_vib  = (byte)((data >> 6) & 0x01);
                slot.reg_type = (byte)((data >> 5) & 0x01);
                slot.reg_ksr  = (byte)((data >> 4) & 0x01);
                slot.reg_mult = (byte)(data & 0x0f);
            }
        }
Beispiel #7
0
 static void OPL3_SlotWrite60(ref opl3_slot slot, byte data)
 {
     slot.reg_ar = (byte)((data >> 4) & 0x0f);
     slot.reg_dr = (byte)(data & 0x0f);
 }
Beispiel #8
0
 static void OPL3_SlotWrite40(ref opl3_slot slot, byte data)
 {
     slot.reg_ksl = (byte)((data >> 6) & 0x03);
     slot.reg_tl  = (byte)(data & 0x3f);
     OPL3_EnvelopeUpdateKSL(ref slot);
 }
Beispiel #9
0
        //
        // Phase Generator
        //

        public static void OPL3_PhaseGenerate(ref opl3_slot slot)
        {
            opl3_chip chip;
            ushort    f_num;
            uint      basefreq;
            byte      rm_xor, n_bit;
            uint      noise;
            ushort    phase;

            chip  = slot.chip;
            f_num = slot.channel.f_num;
            if (slot.reg_vib != 0)
            {
                sbyte range;
                byte  vibpos;

                range  = (sbyte)((f_num >> 7) & 7);
                vibpos = slot.chip.vibpos;

                if ((vibpos & 3) == 0)
                {
                    range = 0;
                }
                else if ((vibpos & 1) != 0)
                {
                    range >>= 1;
                }
                range >>= slot.chip.vibshift;

                if ((vibpos & 4) != 0)
                {
                    range = (sbyte)-range;
                }
                f_num += (ushort)range;
            }
            basefreq = (uint)((f_num << slot.channel.block) >> 1);
            phase    = (ushort)(slot.pg_phase >> 9);
            if (slot.pg_reset != 0)
            {
                slot.pg_phase = 0;
            }
            slot.pg_phase += (basefreq * mt[slot.reg_mult]) >> 1;
            // Rhythm mode
            noise             = chip.noise;
            slot.pg_phase_out = phase;
            if (slot.slot_num == 13) // hh
            {
                chip.rm_hh_bit2 = (byte)((phase >> 2) & 1);
                chip.rm_hh_bit3 = (byte)((phase >> 3) & 1);
                chip.rm_hh_bit7 = (byte)((phase >> 7) & 1);
                chip.rm_hh_bit8 = (byte)((phase >> 8) & 1);
            }
            if (slot.slot_num == 17 && (chip.rhy & 0x20) != 0) // tc
            {
                chip.rm_tc_bit3 = (byte)((phase >> 3) & 1);
                chip.rm_tc_bit5 = (byte)((phase >> 5) & 1);
            }
            if ((chip.rhy & 0x20) != 0)
            {
                rm_xor = (byte)((chip.rm_hh_bit2 ^ chip.rm_hh_bit7) | (chip.rm_hh_bit3 ^ chip.rm_tc_bit5) | (chip.rm_tc_bit3 ^ chip.rm_tc_bit5));
                switch (slot.slot_num)
                {
                case 13:     // hh
                    slot.pg_phase_out = (ushort)(rm_xor << 9);
                    if ((rm_xor ^ (noise & 1)) != 0)
                    {
                        slot.pg_phase_out |= 0xd0;
                    }
                    else
                    {
                        slot.pg_phase_out |= 0x34;
                    }
                    break;

                case 16:     // sd
                    slot.pg_phase_out = (ushort)((chip.rm_hh_bit8 << 9) | ((chip.rm_hh_bit8 ^ (noise & 1)) << 8));
                    break;

                case 17:     // tc
                    slot.pg_phase_out = (ushort)((rm_xor << 9) | 0x80);
                    break;

                default:
                    break;
                }
            }
            n_bit      = (byte)(((noise >> 14) ^ noise) & 0x01);
            chip.noise = (byte)((noise >> 1) | (n_bit << 22));
        }
Beispiel #10
0
 public static void OPL3_EnvelopeKeyOff(ref opl3_slot slot, EnvelopeKeyType type)
 {
     slot.key &= (byte)~type;
 }
Beispiel #11
0
 static void OPL3_EnvelopeKeyOn(ref opl3_slot slot, EnvelopeKeyType type)
 {
     slot.key |= (byte)type;
 }
Beispiel #12
0
        public static void OPL3_EnvelopeCalc(ref opl3_slot slot)
        {
            byte   nonzero;
            byte   rate;
            byte   rate_hi;
            byte   rate_lo;
            byte   reg_rate = 0;
            byte   ks;
            byte   eg_shift, shift;
            ushort eg_rout;
            short  eg_inc;
            byte   eg_off;
            byte   reset = 0;

            //unsafe
            //{
            //    slot.eg_out = (short)(slot.eg_rout + (slot.reg_tl << 2) + (slot.eg_ksl >> kslshift[slot.reg_ksl]) + *slot.trem);
            //}
            slot.eg_out = (short)(slot.eg_rout + (slot.reg_tl << 2) + (slot.eg_ksl >> kslshift[slot.reg_ksl]) + (slot.tremZero == false ? slot.chip.tremolo : 0));
            if (slot.key != 0 && slot.eg_gen == envelope_gen_num.release)
            {
                reset    = 1;
                reg_rate = slot.reg_ar;
            }
            else
            {
                switch (slot.eg_gen)
                {
                case envelope_gen_num.attack:
                    reg_rate = slot.reg_ar;
                    break;

                case envelope_gen_num.decay:
                    reg_rate = slot.reg_dr;
                    break;

                case envelope_gen_num.sustain:
                    unsafe
                    {
                        if (slot.reg_type == 0)
                        {
                            reg_rate = slot.reg_rr;
                        }
                    }
                    break;

                case envelope_gen_num.release:
                    reg_rate = slot.reg_rr;
                    break;
                }
            }
            slot.pg_reset = reset;
            ks            = (byte)(slot.channel.ksv >> ((slot.reg_ksr ^ 1) << 1));
            nonzero       = (byte)((reg_rate != 0) ? 1 : 0);
            rate          = (byte)(ks + (reg_rate << 2));
            rate_hi       = (byte)(rate >> 2);
            rate_lo       = (byte)(rate & 0x03);
            if ((rate_hi & 0x10) != 0)
            {
                rate_hi = 0x0f;
            }
            eg_shift = (byte)(rate_hi + slot.chip.eg_add);
            shift    = 0;
            if (nonzero != 0)
            {
                if (rate_hi < 12)
                {
                    if (slot.chip.eg_state != 0)
                    {
                        switch (eg_shift)
                        {
                        case 12:
                            shift = 1;
                            break;

                        case 13:
                            shift = (byte)((rate_lo >> 1) & 0x01);
                            break;

                        case 14:
                            shift = (byte)(rate_lo & 0x01);
                            break;

                        default:
                            break;
                        }
                    }
                }
                else
                {
                    shift = (byte)((rate_hi & 0x03) + eg_incstep[rate_lo][slot.chip.timer & 0x03]);
                    if ((shift & 0x04) != 0)
                    {
                        shift = 0x03;
                    }
                    if (shift == 0)
                    {
                        shift = slot.chip.eg_state;
                    }
                }
            }
            eg_rout = (ushort)slot.eg_rout;
            eg_inc  = 0;
            eg_off  = 0;
            // Instant attack
            if (reset != 0 && rate_hi == 0x0f)
            {
                eg_rout = 0x00;
            }
            // Envelope off
            if ((slot.eg_rout & 0x1f8) == 0x1f8)
            {
                eg_off = 1;
            }
            if (slot.eg_gen != envelope_gen_num.attack && reset == 0 && eg_off != 0)
            {
                eg_rout = 0x1ff;
            }
            switch (slot.eg_gen)
            {
            case envelope_gen_num.attack:
                if (slot.eg_rout == 0)
                {
                    slot.eg_gen = envelope_gen_num.decay;
                }
                else if (slot.key != 0 && shift > 0 && rate_hi != 0x0f)
                {
                    eg_inc = (short)(((~slot.eg_rout) << shift) >> 4);
                }
                break;

            case envelope_gen_num.decay:
                if ((slot.eg_rout >> 4) == slot.reg_sl)
                {
                    slot.eg_gen = envelope_gen_num.sustain;
                }
                else if (eg_off == 0 && reset == 0 && shift > 0)
                {
                    eg_inc = (short)(1 << (shift - 1));
                }
                break;

            case envelope_gen_num.sustain:
            case envelope_gen_num.release:
                if (eg_off == 0 && reset == 0 && shift > 0)
                {
                    eg_inc = (short)(1 << (shift - 1));
                }
                break;
            }
            slot.eg_rout = (short)((eg_rout + eg_inc) & 0x1ff);
            // Key off
            if (reset != 0)
            {
                slot.eg_gen = envelope_gen_num.attack;
            }
            if (slot.key == 0)
            {
                slot.eg_gen = envelope_gen_num.release;
            }
        }