1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 1999,2000 Tatsuyuki Satoh
5 * Copyright (C) 2001,2002 Ben Parnell
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* This file has been heavily modified from the original(mostly unused
23 code was removed). If you want to use it for anything other than
24 VRC7 sound emulation, you should get the original from the AdPlug
25 source distribution or the MAME(version 0.37b16) source distribution
26 (but be careful about the different licenses).
39 #define PI 3.14159265358979323846
42 /* -------------------- preliminary define section --------------------- */
43 /* attack/decay rate time rate */
44 #define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
45 #define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
47 #define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
49 #define FREQ_BITS 24 /* frequency turn */
51 /* counter bits = 20 , octerve 7 */
52 #define FREQ_RATE (1<<(FREQ_BITS-20))
53 #define TL_BITS (FREQ_BITS+2)
55 /* final output shift , limit minimum and maximum */
56 #define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
57 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB<<3)
58 #define OPL_MINOUT (-0x8000<<OPL_OUTSB<<3)
60 /* -------------------- quality selection --------------------- */
63 /* used static memory = SIN_ENT * 4 (byte) */
66 /* output level entries (envelope,sinwave) */
67 /* envelope counter lower bits */
69 /* envelope output entries */
71 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
72 /* used static memory = EG_ENT*4 (byte) */
74 #define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */
76 #define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */
78 #define EG_AST 0 /* ATTACK START */
80 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
82 /* LFO table entries */
84 #define VIB_SHIFT (32-9)
86 #define AMS_SHIFT (32-9)
90 /* -------------------- local defines , macros --------------------- */
92 /* register number to channel number , slot offset */
97 #define ENV_MOD_RR 0x00
98 #define ENV_MOD_DR 0x01
99 #define ENV_MOD_AR 0x02
101 /* -------------------- tables --------------------- */
102 static const int slot_array[32]=
104 0, 2, 4, 1, 3, 5,-1,-1,
105 6, 8,10, 7, 9,11,-1,-1,
106 12,14,16,13,15,17,-1,-1,
107 -1,-1,-1,-1,-1,-1,-1,-1
110 /* key scale level */
111 /* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
112 #define DV (EG_STEP/2)
113 static const UINT32 KSL_TABLE[8*16]=
116 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
117 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
118 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
119 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
121 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
122 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
123 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
124 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
126 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
127 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
128 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
129 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
131 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
132 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
133 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
134 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
136 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
137 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
138 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
139 10.875/DV,11.250/DV,11.625/DV,12.000/DV,
141 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
142 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
143 12.000/DV,12.750/DV,13.125/DV,13.500/DV,
144 13.875/DV,14.250/DV,14.625/DV,15.000/DV,
146 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
147 12.000/DV,13.125/DV,13.875/DV,14.625/DV,
148 15.000/DV,15.750/DV,16.125/DV,16.500/DV,
149 16.875/DV,17.250/DV,17.625/DV,18.000/DV,
151 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
152 15.000/DV,16.125/DV,16.875/DV,17.625/DV,
153 18.000/DV,18.750/DV,19.125/DV,19.500/DV,
154 19.875/DV,20.250/DV,20.625/DV,21.000/DV
158 /* sustain lebel table (3db per step) */
159 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
160 #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
161 static const INT32 SL_TABLE[16]={
162 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
163 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
167 #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
168 /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
169 /* TL_TABLE[ 0 to TL_MAX ] : plus section */
170 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
171 static INT32 *TL_TABLE;
173 /* pointers to TL_TABLE with sinwave output offset */
174 static INT32 **SIN_TABLE;
177 static INT32 *AMS_TABLE;
178 static INT32 *VIB_TABLE;
180 /* envelope output curve table */
181 /* attack + decay + OFF */
182 static INT32 ENV_CURVE[2*EG_ENT+1];
186 static const UINT32 MUL_TABLE[16]= {
187 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
188 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
189 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
193 /* dummy attack / decay rate ( when rate == 0 ) */
194 static INT32 RATE_0[16]=
195 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
197 /* -------------------- static state --------------------- */
199 /* lock level of common table */
200 static int num_lock = 0;
203 static void *cur_chip = NULL; /* current chip point */
204 /* currenct chip state */
205 /* static OPLSAMPLE *bufL,*bufR; */
208 OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
210 static INT32 outd[1];
215 static INT32 amsIncr;
216 static INT32 vibIncr;
217 static INT32 feedback2; /* connect for SLOT 2 */
219 /* --------------------- subroutines --------------------- */
221 INLINE int Limit( int val, int max, int min ) {
224 else if ( val < min )
230 /* ----- key on ----- */
231 INLINE void OPL_KEYON(OPL_SLOT *SLOT)
233 /* sin wave restart */
236 SLOT->evm = ENV_MOD_AR;
237 SLOT->evs = SLOT->evsa;
241 /* ----- key off ----- */
242 INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
244 if( SLOT->evm > ENV_MOD_RR)
246 /* set envelope counter from envleope output */
247 SLOT->evm = ENV_MOD_RR;
248 if( !(SLOT->evc&EG_DST) )
249 //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
252 SLOT->evs = SLOT->evsr;
256 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
257 /* return : envelope output */
258 INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
260 /* calcrate envelope generator */
261 if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
264 case ENV_MOD_AR: /* ATTACK -> DECAY1 */
266 SLOT->evm = ENV_MOD_DR;
268 SLOT->eve = SLOT->SL;
269 SLOT->evs = SLOT->evsd;
271 case ENV_MOD_DR: /* DECAY -> SL or RR */
272 SLOT->evc = SLOT->SL;
280 SLOT->evm = ENV_MOD_RR;
281 SLOT->evs = SLOT->evsr;
284 case ENV_MOD_RR: /* RR -> OFF */
286 SLOT->eve = EG_OFF+1;
291 /* calcrate envelope */
292 return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
295 /* set algorythm connection */
296 static void set_algorythm( OPL_CH *CH)
298 INT32 *carrier = &outd[0];
299 CH->connect1 = CH->CON ? carrier : &feedback2;
300 CH->connect2 = carrier;
303 /* ---------- frequency counter for operater update ---------- */
304 INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
308 /* frequency step counter */
309 SLOT->Incr = CH->fc * SLOT->mul;
310 ksr = CH->kcode >> SLOT->KSR;
312 if( SLOT->ksr != ksr )
315 /* attack , decay rate recalcration */
316 SLOT->evsa = SLOT->AR[ksr];
317 SLOT->evsd = SLOT->DR[ksr];
318 SLOT->evsr = SLOT->RR[ksr];
320 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
323 /* set multi,am,vib,EG-TYP,KSR,mul */
324 INLINE void set_mul(FM_OPL *OPL,int slot,int v)
326 OPL_CH *CH = &OPL->P_CH[slot/2];
327 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
329 SLOT->mul = MUL_TABLE[v&0x0f];
330 SLOT->KSR = (v&0x10) ? 0 : 2;
331 SLOT->eg_typ = (v&0x20)>>5;
332 SLOT->vib = (v&0x40);
333 SLOT->ams = (v&0x80);
334 CALC_FCSLOT(CH,SLOT);
338 INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
340 OPL_CH *CH = &OPL->P_CH[slot/2];
341 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
342 int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
345 // if(ksl) {sprintf(errmsg,"doh");howlong=255;ksl=0;}
347 SLOT->ksl = ksl ? ksl : 31;
348 // SLOT->ksl = ksl ? 3-ksl : 31;
349 SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
351 if( !(OPL->mode&0x80) )
352 { /* not CSM latch total level */
353 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
357 /* set attack rate & decay rate */
358 INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
360 OPL_CH *CH = &OPL->P_CH[slot/2];
361 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
365 SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
366 SLOT->evsa = SLOT->AR[SLOT->ksr];
367 if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
369 SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
370 SLOT->evsd = SLOT->DR[SLOT->ksr];
371 if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
374 /* set sustain level & release rate */
375 INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
377 OPL_CH *CH = &OPL->P_CH[slot/2];
378 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
382 SLOT->SL = SL_TABLE[sl];
383 if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
384 SLOT->RR = &OPL->DR_TABLE[rr<<2];
385 SLOT->evsr = SLOT->RR[SLOT->ksr];
386 if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
389 /* operator output calcrator */
390 #define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
391 /* ---------- calcrate one of channel ---------- */
392 INLINE void OPL_CALC_CH( OPL_CH *CH )
399 SLOT = &CH->SLOT[SLOT1];
400 env_out=OPL_CALC_SLOT(SLOT);
401 if( env_out < EG_ENT-1 )
404 if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
405 else SLOT->Cnt += SLOT->Incr;
409 int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
410 CH->op1_out[1] = CH->op1_out[0];
411 *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
415 *CH->connect1 += OP_OUT(SLOT,env_out,0);
419 CH->op1_out[1] = CH->op1_out[0];
423 SLOT = &CH->SLOT[SLOT2];
424 env_out=OPL_CALC_SLOT(SLOT);
425 if( env_out < EG_ENT-1 )
428 if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
429 else SLOT->Cnt += SLOT->Incr;
431 outd[0] += OP_OUT(SLOT,env_out, feedback2);
435 /* ----------- initialize time tabls ----------- */
436 static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
441 /* make attack rate & decay rate tables */
442 for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
443 for (i = 4;i <= 60;i++){
444 rate = OPL->freqbase; /* frequency rate */
445 if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
446 rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
447 rate *= (double)(EG_ENT<<ENV_BITS);
448 OPL->AR_TABLE[i] = rate / ARRATE;
449 OPL->DR_TABLE[i] = rate / DRRATE;
451 for (i = 60;i < 76;i++)
453 OPL->AR_TABLE[i] = EG_AED-1;
454 OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
458 /* ---------- generic table initialize ---------- */
459 static int OPLOpenTable( void )
466 /* allocate dynamic tables */
467 if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
469 if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
474 if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
480 if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
487 /* make total level table */
488 for (t = 0;t < EG_ENT-1 ;t++){
489 rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */
490 TL_TABLE[ t] = (int)rate;
491 TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
494 /* fill volume off area */
495 for ( t = EG_ENT-1; t < TL_MAX ;t++){
496 TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
499 /* make sinwave table (total level offet) */
500 /* degree 0 = degree 180 = off */
501 SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
502 for (s = 1;s <= SIN_ENT/4;s++){
503 pom = sin(2*PI*s/SIN_ENT); /* sin */
504 pom = 20*log10(1/pom); /* decibel */
505 j = pom / EG_STEP; /* TL_TABLE steps */
507 /* degree 0 - 90 , degree 180 - 90 : plus section */
508 SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
509 /* degree 180 - 270 , degree 360 - 270 : minus section */
510 SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
513 for (s = 0;s < SIN_ENT;s++)
515 SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
516 SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
517 SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
520 /* envelope counter -> envelope output table */
521 for (i=0; i<EG_ENT; i++)
524 pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
525 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
526 ENV_CURVE[i] = (int)pom;
527 /* DECAY ,RELEASE curve */
528 ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
531 ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
532 /* make LFO ams table */
533 for (i=0; i<AMS_ENT; i++)
535 pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
536 AMS_TABLE[i] = (1.0/EG_STEP)*pom; /* 1dB */
537 AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
539 /* make LFO vibrate table */
540 for (i=0; i<VIB_ENT; i++)
542 /* 100cent = 1seminote = 6% ?? */
543 pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
544 VIB_TABLE[i] = VIB_RATE + (pom*0.07); /* +- 7cent */
545 VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
551 static void OPLCloseTable( void )
559 /* CSM Key Controll */
560 INLINE void CSMKeyControll(OPL_CH *CH)
562 OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
563 OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
567 /* total level latch */
568 slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
569 slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
571 CH->op1_out[0] = CH->op1_out[1] = 0;
576 /* ---------- opl initialize ---------- */
577 static void OPL_initalize(FM_OPL *OPL)
582 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
583 /* make time tables */
584 init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
585 /* make fnumber -> increment counter table */
586 for( fn=0 ; fn < 1024 ; fn++ )
588 OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
591 OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
592 OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
595 /* ---------- write a OPL registers ---------- */
596 static void OPLWriteReg(FM_OPL *OPL, int r, int v)
604 case 0x00: /* 00-1f:controll */
608 /* wave selector enable */
609 if(OPL->type&OPL_TYPE_WAVESEL)
611 OPL->wavesel = v&0x20;
614 /* preset compatible mode */
616 for(c=0;c<OPL->max_ch;c++)
618 OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
619 OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
626 case 0x20: /* am,vib,ksr,eg type,mul */
627 slot = slot_array[r&0x1f];
628 if(slot == -1) return;
632 slot = slot_array[r&0x1f];
633 if(slot == -1) return;
634 set_ksl_tl(OPL,slot,v);
637 slot = slot_array[r&0x1f];
638 if(slot == -1) return;
639 set_ar_dr(OPL,slot,v);
642 slot = slot_array[r&0x1f];
643 if(slot == -1) return;
644 set_sl_rr(OPL,slot,v);
650 /* amsep,vibdep,r,bd,sd,tom,tc,hh */
652 OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
653 OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
657 /* keyon,block,fnum */
658 if( (r&0x0f) > 8) return;
659 CH = &OPL->P_CH[r&0x0f];
662 block_fnum = (CH->block_fnum&0x1f00) | v;
666 int keyon = (v>>5)&1;
667 block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
668 if(CH->keyon != keyon)
670 if( (CH->keyon=keyon) )
672 CH->op1_out[0] = CH->op1_out[1] = 0;
673 OPL_KEYON(&CH->SLOT[SLOT1]);
674 OPL_KEYON(&CH->SLOT[SLOT2]);
678 OPL_KEYOFF(&CH->SLOT[SLOT1]);
679 OPL_KEYOFF(&CH->SLOT[SLOT2]);
684 if(CH->block_fnum != block_fnum)
686 int blockRv = 7-(block_fnum>>10);
687 int fnum = block_fnum&0x3ff;
688 CH->block_fnum = block_fnum;
690 CH->ksl_base = KSL_TABLE[block_fnum>>6];
691 CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
692 CH->kcode = CH->block_fnum>>9;
693 if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
694 CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
695 CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
700 if( (r&0x0f) > 8) return;
701 CH = &OPL->P_CH[r&0x0f];
703 int feedback = (v>>1)&7;
704 CH->FB = feedback ? (8+1) - feedback : 0;
709 case 0xe0: /* wave type */
710 slot = slot_array[r&0x1f];
711 if(slot == -1) return;
712 CH = &OPL->P_CH[slot/2];
715 CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
721 /* lock/unlock for common table */
722 static int OPL_LockTable(void)
725 if(num_lock>1) return 0;
728 /* allocate total level table (128kb space) */
729 if( !OPLOpenTable() )
737 static void OPL_UnLockTable(void)
739 if(num_lock) num_lock--;
746 /*******************************************************************************/
747 /* YM3812 local section */
748 /*******************************************************************************/
750 /* ---------- update one of chip ----------- */
751 void YM3812UpdateOne(FM_OPL *OPL, UINT32 *buffer, int length)
754 UINT32 *buf = buffer;
755 UINT32 amsCnt = OPL->amsCnt;
756 UINT32 vibCnt = OPL->vibCnt;
759 if( (void *)OPL != cur_chip ){
760 cur_chip = (void *)OPL;
761 /* channel pointers */
765 amsIncr = OPL->amsIncr;
766 vibIncr = OPL->vibIncr;
767 ams_table = OPL->ams_table;
768 vib_table = OPL->vib_table;
771 for( i=0; i < length ; i++ )
773 /* channel A channel B channel C */
775 ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
776 vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
779 for(CH=S_CH ; CH < R_CH ; CH++)
782 //data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
783 /* store to sound buffer */
785 int32 d=outd[0]>>OPL_OUTSB;
786 if(d<-32768) d=-32768;
792 OPL->amsCnt = amsCnt;
793 OPL->vibCnt = vibCnt;
796 /* ---------- reset one of chip ---------- */
797 void OPLResetChip(FM_OPL *OPL)
803 OPL->mode = 0; /* normal mode */
805 /* reset with register write */
806 OPLWriteReg(OPL,0x01,0); /* wabesel disable */
807 for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
808 /* reset OPerator paramater */
809 for( c = 0 ; c < OPL->max_ch ; c++ )
811 OPL_CH *CH = &OPL->P_CH[c];
812 /* OPL->P_CH[c].PAN = OPN_CENTER; */
813 for(s = 0 ; s < 2 ; s++ )
816 CH->SLOT[s].wavetable = &SIN_TABLE[0];
817 /* CH->SLOT[s].evm = ENV_MOD_RR; */
818 CH->SLOT[s].evc = EG_OFF;
819 CH->SLOT[s].eve = EG_OFF+1;
825 /* ---------- Create one of vietual YM3812 ---------- */
826 /* 'rate' is sampling rate and 'bufsiz' is the size of the */
827 FM_OPL *OPLCreate(int type, int clock, int rate)
832 int max_ch = 9; /* normaly 9 channels */
834 if( OPL_LockTable() ==-1) return NULL;
835 /* allocate OPL state space */
836 state_size = sizeof(FM_OPL);
837 state_size += sizeof(OPL_CH)*max_ch;
839 /* allocate memory block */
840 ptr = malloc(state_size);
841 if(ptr==NULL) return NULL;
843 memset(ptr,0,state_size);
844 OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
845 OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
847 /* set channel state pointer */
851 OPL->max_ch = max_ch;
852 /* init grobal tables */
860 /* ---------- Destroy one of vietual YM3812 ---------- */
861 void OPLDestroy(FM_OPL *OPL)
867 /* ---------- YM3812 I/O interface ---------- */
868 void OPLWrite(FM_OPL *OPL,UINT8 a,UINT8 v)
870 OPLWriteReg(OPL,a,v);