Exemple #1
0
        private static FM_OPL OPLCreate(int type,int clock,int rate)
        {
            int i;

            OPL_LockTable();
            OPL        = new FM_OPL();
            OPL.P_CH   = new OPL_CH[9];
            OPL.fn_tab = new uint[1024];
            OPL.T      = new uint[2];
            OPL.st     = new byte[2];
            for (i = 0; i < 9; i++)
            {
                OPL.P_CH[i].SLOT            = new OPL_SLOT[2];
                OPL.P_CH[i].SLOT[0].op1_out = new int[2];
                OPL.P_CH[i].SLOT[1].op1_out = new int[2];
            }
            OPL.type  = (byte)type;
            OPL.clock = clock;
            OPL.rate  = rate;
            OPL_initalize();
            return(OPL);
        }
Exemple #2
0
        public static FM_OPL OPLCreate(int type, int clock, int rate)
        {
            FM_OPL OPL;
            int max_ch = 9; /* normaly 9 channels */

            if (OPL_LockTable() == -1) return null;
            /* allocate OPL state space */
            //state_size = sizeof(FM_OPL);
            //state_size += sizeof(OPL_CH) * max_ch;
#if BUILD_Y8950
            //if ((type & OPL_TYPE_ADPCM)!=0) state_size += sizeof(YM_DELTAT);
#endif
            /* allocate memory block */
            //ptr = malloc(state_size);
            //if (ptr == NULL) return null;
            /* clear */
            //memset(ptr, 0, state_size);
            OPL = new FM_OPL();//(FM_OPL*)ptr; ptr += sizeof(FM_OPL);
            OPL.P_CH = new OPL_CH[max_ch];//(OPL_CH*)ptr; ptr += sizeof(OPL_CH) * max_ch;
            for (int i = 0; i < max_ch; i++)
                OPL.P_CH[i] = new OPL_CH();
#if BUILD_Y8950
            if ((type & OPL_TYPE_ADPCM) != 0)
                OPL.deltat = new YM_DELTAT();//(YM_DELTAT*)ptr; ptr += sizeof(YM_DELTAT);
#endif
            /* set channel state pointer */
            OPL.type = (byte)type;
            OPL.clock = clock;
            OPL.rate = rate;
            OPL.max_ch = max_ch;
            /* init grobal tables */
            OPL_initalize(OPL);
            /* reset chip */
            OPLResetChip(OPL);
            return OPL;
        }
Exemple #3
0
        static void OPLResetChip(FM_OPL OPL)
        {
            int c, s;
            int i;

            /* reset chip */
            OPL.mode = 0;	/* normal mode */
            OPL_STATUS_RESET(OPL, 0x7f);
            /* reset with register write */
            OPLWriteReg(OPL, 0x01, 0); /* wabesel disable */
            OPLWriteReg(OPL, 0x02, 0); /* Timer1 */
            OPLWriteReg(OPL, 0x03, 0); /* Timer2 */
            OPLWriteReg(OPL, 0x04, 0); /* IRQ mask clear */
            for (i = 0xff; i >= 0x20; i--) OPLWriteReg(OPL, i, 0);
            /* reset OPerator paramater */
            for (c = 0; c < OPL.max_ch; c++)
            {
                OPL_CH CH = OPL.P_CH[c];
                /* OPL.P_CH[c].PAN = OPN_CENTER; */
                for (s = 0; s < 2; s++)
                {
                    /* wave table */
                    //throw new Exception();
                    CH.SLOT[s].wti = 0;
                    CH.SLOT[s].wavetable = SIN_TABLE;
                    /* CH.SLOT[s].evm = ENV_MOD_RR; */
                    CH.SLOT[s].evc = EG_OFF;
                    CH.SLOT[s].eve = EG_OFF + 1;
                    CH.SLOT[s].evs = 0;
                }
            }
#if BUILD_Y8950
            if ((OPL.type & OPL_TYPE_ADPCM) != 0)
            {
                YM_DELTAT DELTAT = OPL.deltat;

                DELTAT.freqbase = OPL.freqbase;
                DELTAT.output_pointer = outd;
                DELTAT.portshift = 5;
                DELTAT.output_range = DELTAT_MIXING_LEVEL << TL_BITS;
                YM_DELTA_T.YM_DELTAT_ADPCM_Reset(DELTAT, 0);
            }
#endif
        }
Exemple #4
0
        static void OPLWriteReg(FM_OPL OPL, int r, int v)
        {
            OPL_CH CH;
            int slot;
            int block_fnum;

            switch (r & 0xe0)
            {
                case 0x00: /* 00-1f:controll */
                    switch (r & 0x1f)
                    {
                        case 0x01:
                            /* wave selector enable */
                            if ((OPL.type & OPL_TYPE_WAVESEL) != 0)
                            {
                                OPL.wavesel = (byte)(v & 0x20);
                                if (OPL.wavesel == 0)
                                {
                                    /* preset compatible mode */
                                    int c;
                                    for (c = 0; c < OPL.max_ch; c++)
                                    {
                                        OPL.P_CH[c].SLOT[SLOT1].wti = 0;
                                        OPL.P_CH[c].SLOT[SLOT1].wavetable = SIN_TABLE;
                                        OPL.P_CH[c].SLOT[SLOT2].wavetable = SIN_TABLE;
                                    }
                                }
                            }
                            return;
                        case 0x02:	/* Timer 1 */
                            OPL.T[0] = (256 - v) * 4;
                            break;
                        case 0x03:	/* Timer 2 */
                            OPL.T[1] = (256 - v) * 16;
                            return;
                        case 0x04:	/* IRQ clear / mask and Timer enable */
                            if ((v & 0x80) != 0)
                            {	/* IRQ flag clear */
                                OPL_STATUS_RESET(OPL, 0x7f);
                            }
                            else
                            {	/* set IRQ mask ,timer enable*/
                                byte st1 = (byte)(v & 1);
                                byte st2 = (byte)((v >> 1) & 1);
                                /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
                                OPL_STATUS_RESET(OPL, v & 0x78);
                                OPL_STATUSMASK_SET(OPL, ((~v) & 0x78) | 0x01);
                                /* timer 2 */
                                if (OPL.st[1] != st2)
                                {
                                    double interval = st2 != 0 ? (double)OPL.T[1] * OPL.TimerBase : 0.0;
                                    OPL.st[1] = st2;
                                    if (OPL.TimerHandler != null) OPL.TimerHandler(OPL.TimerParam + 1, interval);
                                }
                                /* timer 1 */
                                if (OPL.st[0] != st1)
                                {
                                    double interval = st1 != 0 ? (double)OPL.T[0] * OPL.TimerBase : 0.0;
                                    OPL.st[0] = st1;
                                    if (OPL.TimerHandler != null) OPL.TimerHandler(OPL.TimerParam + 0, interval);
                                }
                            }
                            return;
#if BUILD_Y8950
                        case 0x06:		/* Key Board OUT */
                            if ((OPL.type & OPL_TYPE_KEYBOARD) != 0)
                            {
                                if (OPL.keyboardhandler_w != null)
                                    OPL.keyboardhandler_w(OPL.keyboard_param, (byte)v);
                                else
                                    Mame.printf("OPL:write unmapped KEYBOARD port\n");
                            }
                            return;
                        case 0x07:	/* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
                            if ((OPL.type & OPL_TYPE_ADPCM) != 0)
                                YM_DELTA_T.YM_DELTAT_ADPCM_Write(OPL.deltat, r - 0x07, v);
                            return;
                        case 0x08:	/* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
                            OPL.mode = (uint)v;
                            v &= 0x1f;	/* for DELTA-T unit */
                            goto case 0x09;
                        case 0x09:		/* START ADD */
                        case 0x0a:
                        case 0x0b:		/* STOP ADD  */
                        case 0x0c:
                        case 0x0d:		/* PRESCALE   */
                        case 0x0e:
                        case 0x0f:		/* ADPCM data */
                        case 0x10: 		/* DELTA-N    */
                        case 0x11: 		/* DELTA-N    */
                        case 0x12: 		/* EG-CTRL    */
                            if ((OPL.type & OPL_TYPE_ADPCM) != 0)
                                YM_DELTA_T.YM_DELTAT_ADPCM_Write(OPL.deltat, r - 0x07, v);
                            return;
#if false
		case 0x15:		/* DAC data    */
		case 0x16:
		case 0x17:		/* SHIFT    */
			return;
		case 0x18:		/* I/O CTRL (Direction) */
			if(OPL.type&OPL_TYPE_IO)
				OPL.portDirection = v&0x0f;
			return;
		case 0x19:		/* I/O DATA */
			if(OPL.type&OPL_TYPE_IO)
			{
				OPL.portLatch = v;
				if(OPL.porthandler_w)
					OPL.porthandler_w(OPL.port_param,v&OPL.portDirection);
			}
			return;
		case 0x1a:		/* PCM data */
			return;
#endif
#endif
                    }
                    break;
                case 0x20:	/* am,vib,ksr,eg type,mul */
                    slot = slot_array[r & 0x1f];
                    if (slot == -1) return;
                    set_mul(OPL, slot, v);
                    return;
                case 0x40:
                    slot = slot_array[r & 0x1f];
                    if (slot == -1) return;
                    set_ksl_tl(OPL, slot, v);
                    return;
                case 0x60:
                    slot = slot_array[r & 0x1f];
                    if (slot == -1) return;
                    set_ar_dr(OPL, slot, v);
                    return;
                case 0x80:
                    slot = slot_array[r & 0x1f];
                    if (slot == -1) return;
                    set_sl_rr(OPL, slot, v);
                    return;
                case 0xa0:
                    switch (r)
                    {
                        case 0xbd:
                            /* amsep,vibdep,r,bd,sd,tom,tc,hh */
                            {
                                byte rkey = (byte)(OPL.rythm ^ v);
                                OPL.ams_table = new IntSubArray(AMS_TABLE, (v & 0x80) != 0 ? AMS_ENT : 0);
                                OPL.vib_table = new IntSubArray(VIB_TABLE, (v & 0x40) != 0 ? VIB_ENT : 0);
                                OPL.rythm = (byte)(v & 0x3f);
                                if ((OPL.rythm & 0x20) != 0)
                                {
#if false
				usrintf_showmessage("OPL Rythm mode select");
#endif
                                    /* BD key on/off */
                                    if ((rkey & 0x10) != 0)
                                    {
                                        if ((v & 0x10) != 0)
                                        {
                                            OPL.P_CH[6].op1_out[0] = OPL.P_CH[6].op1_out[1] = 0;
                                            OPL_KEYON(OPL.P_CH[6].SLOT[SLOT1]);
                                            OPL_KEYON(OPL.P_CH[6].SLOT[SLOT2]);
                                        }
                                        else
                                        {
                                            OPL_KEYOFF(OPL.P_CH[6].SLOT[SLOT1]);
                                            OPL_KEYOFF(OPL.P_CH[6].SLOT[SLOT2]);
                                        }
                                    }
                                    /* SD key on/off */
                                    if ((rkey & 0x08) != 0)
                                    {
                                        if ((v & 0x08) != 0) OPL_KEYON(OPL.P_CH[7].SLOT[SLOT2]);
                                        else OPL_KEYOFF(OPL.P_CH[7].SLOT[SLOT2]);
                                    }/* TAM key on/off */
                                    if ((rkey & 0x04) != 0)
                                    {
                                        if ((v & 0x04) != 0) OPL_KEYON(OPL.P_CH[8].SLOT[SLOT1]);
                                        else OPL_KEYOFF(OPL.P_CH[8].SLOT[SLOT1]);
                                    }
                                    /* TOP-CY key on/off */
                                    if ((rkey & 0x02) != 0)
                                    {
                                        if ((v & 0x02) != 0) OPL_KEYON(OPL.P_CH[8].SLOT[SLOT2]);
                                        else OPL_KEYOFF(OPL.P_CH[8].SLOT[SLOT2]);
                                    }
                                    /* HH key on/off */
                                    if ((rkey & 0x01) != 0)
                                    {
                                        if ((v & 0x01) != 0) OPL_KEYON(OPL.P_CH[7].SLOT[SLOT1]);
                                        else OPL_KEYOFF(OPL.P_CH[7].SLOT[SLOT1]);
                                    }
                                }
                            }
                            return;
                    }
                    /* keyon,block,fnum */
                    if ((r & 0x0f) > 8) return;
                    CH = OPL.P_CH[r & 0x0f];
                    if ((r & 0x10) == 0)
                    {	/* a0-a8 */
                        block_fnum = (int)(CH.block_fnum & 0x1f00) | v;
                    }
                    else
                    {	/* b0-b8 */
                        int keyon = (v >> 5) & 1;
                        block_fnum = (int)(((v & 0x1f) << 8) | (CH.block_fnum & 0xff));
                        if (CH.keyon != keyon)
                        {
                            if ((CH.keyon = (byte)keyon) != 0)
                            {
                                CH.op1_out[0] = CH.op1_out[1] = 0;
                                OPL_KEYON(CH.SLOT[SLOT1]);
                                OPL_KEYON(CH.SLOT[SLOT2]);
                            }
                            else
                            {
                                OPL_KEYOFF(CH.SLOT[SLOT1]);
                                OPL_KEYOFF(CH.SLOT[SLOT2]);
                            }
                        }
                    }
                    /* update */
                    if (CH.block_fnum != block_fnum)
                    {
                        int blockRv = 7 - (block_fnum >> 10);
                        int fnum = block_fnum & 0x3ff;
                        CH.block_fnum = (uint)block_fnum;

                        CH.ksl_base = KSL_TABLE[block_fnum >> 6];
                        CH.fc = OPL.FN_TABLE[fnum] >> blockRv;
                        CH.kcode = (byte)(CH.block_fnum >> 9);
                        if ((OPL.mode & 0x40) != 0 && (CH.block_fnum & 0x100) != 0) CH.kcode |= 1;
                        CALC_FCSLOT(CH, CH.SLOT[SLOT1]);
                        CALC_FCSLOT(CH, CH.SLOT[SLOT2]);
                    }
                    return;
                case 0xc0:
                    /* FB,C */
                    if ((r & 0x0f) > 8) return;
                    CH = OPL.P_CH[r & 0x0f];
                    {
                        int feedback = (v >> 1) & 7;
                        CH.FB = (byte)(feedback != 0 ? (8 + 1) - feedback : 0);
                        CH.CON = (byte)(v & 1);
                        set_algorythm(CH);
                    }
                    return;
                case 0xe0: /* wave type */
                    slot = slot_array[r & 0x1f];
                    if (slot == -1) return;
                    CH = OPL.P_CH[slot / 2];
                    if (OPL.wavesel != 0)
                    {
                        /* Log(LOG_INF,"OPL SLOT %d wave select %d\n",slot,v&3); */
                        throw new Exception();
                        //CH.SLOT[slot & 1].wavetable = new IntSubArray(SIN_TABLE[(v & 0x03) * SIN_ENT]);
                    }
                    return;
            }
        }
Exemple #5
0
        /* set multi,am,vib,EG-TYP,KSR,mul */
        static void set_mul(FM_OPL OPL, int slot, int v)
        {
            OPL_CH CH = OPL.P_CH[slot / 2];
            OPL_SLOT SLOT = CH.SLOT[slot & 1];

            SLOT.mul = MUL_TABLE[v & 0x0f];
            SLOT.KSR = ((v & 0x10) != 0) ? (byte)0 : (byte)2;
            SLOT.eg_typ = (byte)((v & 0x20) >> 5);
            SLOT.vib = (byte)((v & 0x40));
            SLOT.ams = (byte)(v & 0x80);
            CALC_FCSLOT(CH, SLOT);
        }
Exemple #6
0
        public static void YM3812UpdateOne(FM_OPL OPL, _ShortPtr buffer, int length)
        {
            int i;
            int data;
            _ShortPtr buf = buffer;
            uint amsCnt = (uint)OPL.amsCnt;
            uint vibCnt = (uint)OPL.vibCnt;
            byte rythm = (byte)(OPL.rythm & 0x20);
            OPL_CH CH;
            int R_CH;

            if ((object)OPL != cur_chip)
            {
                cur_chip = OPL;
                /* channel pointers */
                S_CH = OPL.P_CH;
                E_CH = 9;// S_CH[9];
                /* rythm slot */
                SLOT7_1 = S_CH[7].SLOT[SLOT1];
                SLOT7_2 = S_CH[7].SLOT[SLOT2];
                SLOT8_1 = S_CH[8].SLOT[SLOT1];
                SLOT8_2 = S_CH[8].SLOT[SLOT2];
                /* LFO state */
                amsIncr = OPL.amsIncr;
                vibIncr = OPL.vibIncr;
                ams_table = OPL.ams_table;
                vib_table = OPL.vib_table;
            }
            R_CH = rythm != 0 ? 6 : E_CH;
            for (i = 0; i < length; i++)
            {
                /*            channel A         channel B         channel C      */
                /* LFO */
                ams = ams_table[(int)((amsCnt += (uint)amsIncr) >> AMS_SHIFT)];
                vib = vib_table[(int)((vibCnt += (uint)vibIncr) >> VIB_SHIFT)];
                outd[0] = 0;
                /* FM part */
                for (int k = 0; k != R_CH; k++)
                {
                    CH = S_CH[k];
                    //for(CH=S_CH ; CH < R_CH ; CH++)
                    OPL_CALC_CH(CH);
                }
                /* Rythn part */
                if (rythm != 0)
                    OPL_CALC_RH(S_CH);
                /* limit check */
                data = Limit(outd[0], OPL_MAXOUT, OPL_MINOUT);
                /* store to sound buffer */
                buf.write16(i, (ushort)(data >> OPL_OUTSB));
            }

            OPL.amsCnt = (int)amsCnt;
            OPL.vibCnt = (int)vibCnt;
        }
Exemple #7
0
 public static void OPLSetKeyboardHandler(FM_OPL OPL, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, int param)
 {
     OPL.keyboardhandler_w = KeyboardHandler_w;
     OPL.keyboardhandler_r = KeyboardHandler_r;
     OPL.keyboard_param = param;
 }
Exemple #8
0
 public static void OPLSetUpdateHandler(FM_OPL OPL, OPL_UPDATEHANDLER UpdateHandler, int param)
 {
     OPL.UpdateHandler = UpdateHandler;
     OPL.UpdateParam = param;
 }
Exemple #9
0
        static void init_timetables(FM_OPL OPL, int ARRATE, int DRRATE)
        {
            int i;
            double rate;

            /* make attack rate & decay rate tables */
            for (i = 0; i < 4; i++) OPL.AR_TABLE[i] = OPL.DR_TABLE[i] = 0;
            for (i = 4; i <= 60; i++)
            {
                rate = OPL.freqbase;						/* frequency rate */
                if (i < 60) rate *= 1.0 + (i & 3) * 0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
                rate *= 1 << ((i >> 2) - 1);						/* b2-5 : shift bit */
                rate *= (double)(EG_ENT << ENV_BITS);
                OPL.AR_TABLE[i] = (int)(rate / ARRATE);
                OPL.DR_TABLE[i] = (int)(rate / DRRATE);
            }
            for (i = 60; i < 75; i++)
            {
                OPL.AR_TABLE[i] = EG_AED - 1;
                OPL.DR_TABLE[i] = OPL.DR_TABLE[60];
            }
#if false
	for (i = 0;i < 64 ;i++){	/* make for overflow area */
		Log(LOG_WAR,"rate %2d , ar %f ms , dr %f ms \n",i,
			((double)(EG_ENT<<ENV_BITS) / OPL.AR_TABLE[i]) * (1000.0 / OPL.rate),
			((double)(EG_ENT<<ENV_BITS) / OPL.DR_TABLE[i]) * (1000.0 / OPL.rate) );
	}
#endif
        }
Exemple #10
0
 public static void OPLDestroy(ref FM_OPL OPL)
 {
     OPL_UnLockTable();
     OPL = null;
 }
Exemple #11
0
        public static byte OPLRead(FM_OPL OPL, int a)
        {
            if( (a&1) ==0)
	{	/* status port */
		return (byte)(OPL.status & (OPL.statusmask|0x80));
	}
	/* data port */
	switch(OPL.address)
	{
	case 0x05: /* KeyBoard IN */
		if((OPL.type&OPL_TYPE_KEYBOARD)!=0)
		{
			if(OPL.keyboardhandler_r!=null)
				return OPL.keyboardhandler_r(OPL.keyboard_param);
			else
			Mame.printf("OPL:read unmapped KEYBOARD port\n");
		}
		return 0;
#if false
	case 0x0f: /* ADPCM-DATA  */
		return 0;
#endif
	case 0x19: /* I/O DATA    */
		if((OPL.type&OPL_TYPE_IO)!=0)
		{
			if(OPL.porthandler_r!=null)
				return OPL.porthandler_r(OPL.port_param);
			else
                Mame.printf("OPL:read unmapped I/O port\n");
		}
		return 0;
	case 0x1a: /* PCM-DATA    */
		return 0;
	}
	return 0;
        }
Exemple #12
0
        public static int OPLWrite(FM_OPL OPL, int a, int v)
        {
            if( (a&1) ==0)
	{	/* address port */
		OPL.address = (byte)(v & 0xff);
	}
	else
	{	/* data port */
		if(OPL.UpdateHandler!=null) OPL.UpdateHandler(OPL.UpdateParam,0);
		OPLWriteReg(OPL,OPL.address,v);
	}
	return OPL.status>>7;
}
Exemple #13
0
        /* set sustain level & release rate */
        static void set_sl_rr(FM_OPL OPL, int slot, int v)
        {
            OPL_CH CH = OPL.P_CH[slot / 2];
            OPL_SLOT SLOT = CH.SLOT[slot & 1];
            int sl = v >> 4;
            int rr = v & 0x0f;

            SLOT.SL = SL_TABLE[sl];
            if (SLOT.evm == ENV_MOD_DR) SLOT.eve = SLOT.SL;
            SLOT.RR = new IntSubArray(OPL.DR_TABLE, rr << 2);
            SLOT.evsr = SLOT.RR[SLOT.ksr];
            if (SLOT.evm == ENV_MOD_RR) SLOT.evs = SLOT.evsr;
        }
Exemple #14
0
        /* set attack rate & decay rate  */
        static void set_ar_dr(FM_OPL OPL, int slot, int v)
        {
            OPL_CH CH = OPL.P_CH[slot / 2];
            OPL_SLOT SLOT = CH.SLOT[slot & 1];
            int ar = v >> 4;
            int dr = v & 0x0f;

            SLOT.AR = ar != 0 ? new IntSubArray(OPL.AR_TABLE, ar << 2) : new IntSubArray(RATE_0);
            SLOT.evsa = SLOT.AR[SLOT.ksr];
            if (SLOT.evm == ENV_MOD_AR) SLOT.evs = SLOT.evsa;

            SLOT.DR = dr != 0 ? new IntSubArray(OPL.DR_TABLE, dr << 2) : new IntSubArray(RATE_0);
            SLOT.evsd = SLOT.DR[SLOT.ksr];
            if (SLOT.evm == ENV_MOD_DR) SLOT.evs = SLOT.evsd;
        }
Exemple #15
0
        /* set ksl & tl */
        static void set_ksl_tl(FM_OPL OPL, int slot, int v)
        {
            OPL_CH CH = OPL.P_CH[slot / 2];
            OPL_SLOT SLOT = CH.SLOT[slot & 1];
            int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */

            SLOT.ksl = (byte)(ksl != 0 ? 3 - ksl : 31);
            SLOT.TL = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */

            if ((OPL.mode & 0x80) == 0)
            {	/* not CSM latch total level */
                SLOT.TLL = (int)(SLOT.TL + (CH.ksl_base >> SLOT.ksl));
            }
        }
Exemple #16
0
 public static void OPLSetTimerHandler(FM_OPL OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset)
 {
     OPL.TimerHandler = TimerHandler;
     OPL.TimerParam = channelOffset;
 }
Exemple #17
0
 public static void OPLSetIRQHandler(FM_OPL OPL, OPL_IRQHANDLER IRQHandler, int param)
 {
     OPL.IRQHandler = IRQHandler;
     OPL.IRQParam = param;
 }
Exemple #18
0
        static void OPL_initalize(FM_OPL OPL)
        {
            int fn;

            /* frequency base */
            OPL.freqbase = (OPL.rate) != 0 ? ((double)OPL.clock / OPL.rate) / 72 : 0;
            /* Timer base time */
            OPL.TimerBase = 1.0 / ((double)OPL.clock / 72.0);
            /* make time tables */
            init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
            /* make fnumber . increment counter table */
            for (fn = 0; fn < 1024; fn++)
            {
                OPL.FN_TABLE[fn] = (uint)(OPL.freqbase * fn * FREQ_RATE * (1 << 7) / 2);
            }
            /* LFO freq.table */
            OPL.amsIncr = (int)(OPL.rate != 0 ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL.rate * 3.7 * ((double)OPL.clock / 3600000) : 0);
            OPL.vibIncr = (int)(OPL.rate != 0 ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL.rate * 6.4 * ((double)OPL.clock / 3600000) : 0);
        }
Exemple #19
0
 public static void OPLSetPortHandler(FM_OPL OPL, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, int param)
 {
     OPL.porthandler_w = PortHandler_w;
     OPL.porthandler_r = PortHandler_r;
     OPL.port_param = param;
 }
Exemple #20
0
 static void OPL_STATUS_RESET(FM_OPL OPL, int flag)
 {
     /* reset status flag */
     OPL.status &= (byte)~flag;
     if ((OPL.status & 0x80) != 0)
     {
         if ((OPL.status & OPL.statusmask) == 0)
         {
             OPL.status &= 0x7f;
             /* callback user interrupt handler (IRQ is ON to OFF) */
             if (OPL.IRQHandler != null) OPL.IRQHandler(OPL.IRQParam, 0);
         }
     }
 }
Exemple #21
0
 public static int OPLTimerOver(FM_OPL OPL, int c)
 {
     if (c != 0)
     {	/* Timer B */
         OPL_STATUS_SET(OPL, 0x20);
     }
     else
     {	/* Timer A */
         OPL_STATUS_SET(OPL, 0x40);
         /* CSM mode key,TL controll */
         if ((OPL.mode & 0x80) != 0)
         {	/* CSM mode total level latch and auto key on */
             int ch;
             if (OPL.UpdateHandler != null) OPL.UpdateHandler(OPL.UpdateParam, 0);
             for (ch = 0; ch < 9; ch++)
                 CSMKeyControll(OPL.P_CH[ch]);
         }
     }
     /* reload timer */
     if (OPL.TimerHandler != null) OPL.TimerHandler(OPL.TimerParam + c, (double)OPL.T[c] * OPL.TimerBase);
     return OPL.status >> 7;
 }
Exemple #22
0
 static void OPL_STATUS_SET(FM_OPL OPL, int flag)
 {
     /* set status flag */
     OPL.status |= (byte)flag;
     if ((OPL.status & 0x80) == 0)
     {
         if ((OPL.status & OPL.statusmask) != 0)
         {	/* IRQ on */
             OPL.status |= 0x80;
             /* callback user interrupt handler (IRQ is OFF to ON) */
             if (OPL.IRQHandler != null) OPL.IRQHandler(OPL.IRQParam, 1);
         }
     }
 }
Exemple #23
0
 /* IRQ mask set */
 static void OPL_STATUSMASK_SET(FM_OPL OPL, int flag)
 {
     OPL.statusmask = (byte)flag;
     /* IRQ handling check */
     OPL_STATUS_SET(OPL, 0);
     OPL_STATUS_RESET(OPL, 0);
 }
Exemple #24
0
        public static FM_OPL OPLCreate(int type, int clock, int rate)
        {

            FM_OPL OPL;
            //int state_size;
            int max_ch = 9; /* normaly 9 channels */

            if (OPL_LockTable() == -1) return null;
            /* allocate OPL state space */
            //state_size = sizeof(FM_OPL);
            //state_size += sizeof(OPL_CH) * max_ch;
#if BUILD_Y8950
	if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
#endif
            OPL = new FM_OPL();
            OPL.P_CH = new OPL_CH[max_ch+1];
            for (int i = 0; i < max_ch; i++)
                OPL.P_CH[i] = new OPL_CH();


#if BUILD_Y8950
	if(type&OPL_TYPE_ADPCM) OPL.deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
#endif
            /* set channel state pointer */
            OPL.type = (byte)type;
            OPL.clock = clock;
            OPL.rate = rate;
            OPL.max_ch = max_ch;
            /* init grobal tables */
            OPL_initalize(OPL);
            /* reset chip */
            OPLResetChip(OPL);
            return OPL;
        }