1 /*
2 **
3 ** File: fmopl.c -- software implementation of FM sound generator
4 **
5 ** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
6 **
7 ** Version 0.37a
8 **
9 */
10 
11 /*
12 	preliminary :
13 	Problem :
14 	note:
15 */
16 
17 /* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
18  *
19  * This library is free software; you can redistribute it and/or
20  * modify it under the terms of the GNU Lesser General Public
21  * License as published by the Free Software Foundation; either
22  * version 2.1 of the License, or (at your option) any later version.
23  *
24  * This library is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27  * Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU Lesser General Public
30  * License along with this library; if not, write to the Free Software
31  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
32  */
33 
34 #define INLINE		static inline
35 #define HAS_YM3812	1
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <math.h>
42 /* #include "driver.h" */		/* use M.A.M.E. */
43 #include "fmopl.h"
44 
45 #ifndef PI
46 #define PI 3.14159265358979323846
47 #endif
48 
49 /* -------------------- for debug --------------------- */
50 /* #define OPL_OUTPUT_LOG */
51 #ifdef OPL_OUTPUT_LOG
52 static FILE *opl_dbg_fp = NULL;
53 static FM_OPL *opl_dbg_opl[16];
54 static int opl_dbg_maxchip,opl_dbg_chip;
55 #endif
56 
57 /* -------------------- preliminary define section --------------------- */
58 /* attack/decay rate time rate */
59 #define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
60 #define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
61 
62 #define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
63 
64 #define FREQ_BITS 24			/* frequency turn          */
65 
66 /* counter bits = 20 , octerve 7 */
67 #define FREQ_RATE   (1<<(FREQ_BITS-20))
68 #define TL_BITS    (FREQ_BITS+2)
69 
70 /* final output shift , limit minimum and maximum */
71 #define OPL_OUTSB   (TL_BITS+3-16)		/* OPL output final shift 16bit */
72 #define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
73 #define OPL_MINOUT (-0x8000<<OPL_OUTSB)
74 
75 /* -------------------- quality selection --------------------- */
76 
77 /* sinwave entries */
78 /* used static memory = SIN_ENT * 4 (byte) */
79 #define SIN_ENT 2048
80 
81 /* output level entries (envelope,sinwave) */
82 /* envelope counter lower bits */
83 #define ENV_BITS 16
84 /* envelope output entries */
85 #define EG_ENT   4096
86 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
87 /* used static  memory = EG_ENT*4 (byte)                     */
88 
89 #define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
90 #define EG_DED   EG_OFF
91 #define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
92 #define EG_AED   EG_DST
93 #define EG_AST   0                       /* ATTACK START */
94 
95 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
96 
97 /* LFO table entries */
98 #define VIB_ENT 512
99 #define VIB_SHIFT (32-9)
100 #define AMS_ENT 512
101 #define AMS_SHIFT (32-9)
102 
103 #define VIB_RATE 256
104 
105 /* -------------------- local defines , macros --------------------- */
106 
107 /* register number to channel number , slot offset */
108 #define SLOT1 0
109 #define SLOT2 1
110 
111 /* envelope phase */
112 #define ENV_MOD_RR  0x00
113 #define ENV_MOD_DR  0x01
114 #define ENV_MOD_AR  0x02
115 
116 /* -------------------- tables --------------------- */
117 static const int slot_array[32]= {
118 	0, 2, 4, 1, 3, 5,-1,-1,
119 	6, 8,10, 7, 9,11,-1,-1,
120 	12,14,16,13,15,17,-1,-1,
121 	-1,-1,-1,-1,-1,-1,-1,-1
122 };
123 
124 /* key scale level */
125 /* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
126 #define DV (EG_STEP/2)
127 static const UINT32 KSL_TABLE[8*16]= {
128 	/* OCT 0 */
129 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
130 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
131 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
132 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
133 	/* OCT 1 */
134 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
135 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
136 	0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
137 	1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
138 	/* OCT 2 */
139 	0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
140 	0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
141 	3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
142 	4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
143 	/* OCT 3 */
144 	0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
145 	3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
146 	6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
147 	7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
148 	/* OCT 4 */
149 	0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
150 	6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
151 	9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
152 	10.875/DV,11.250/DV,11.625/DV,12.000/DV,
153 	/* OCT 5 */
154 	0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
155 	9.000/DV,10.125/DV,10.875/DV,11.625/DV,
156 	12.000/DV,12.750/DV,13.125/DV,13.500/DV,
157 	13.875/DV,14.250/DV,14.625/DV,15.000/DV,
158 	/* OCT 6 */
159 	0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
160 	12.000/DV,13.125/DV,13.875/DV,14.625/DV,
161 	15.000/DV,15.750/DV,16.125/DV,16.500/DV,
162 	16.875/DV,17.250/DV,17.625/DV,18.000/DV,
163 	/* OCT 7 */
164 	0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
165 	15.000/DV,16.125/DV,16.875/DV,17.625/DV,
166 	18.000/DV,18.750/DV,19.125/DV,19.500/DV,
167 	19.875/DV,20.250/DV,20.625/DV,21.000/DV
168 };
169 #undef DV
170 
171 /* sustain level table (3db per step) */
172 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
173 #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
174 static const INT32 SL_TABLE[16] = {
175 	SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
176 	SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
177 };
178 #undef SC
179 
180 #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
181 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
182 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
183 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
184 static INT32 *TL_TABLE;
185 
186 /* pointers to TL_TABLE with sinwave output offset */
187 static INT32 **SIN_TABLE;
188 
189 /* LFO table */
190 static INT32 *AMS_TABLE;
191 static INT32 *VIB_TABLE;
192 
193 /* envelope output curve table */
194 /* attack + decay + OFF */
195 static INT32 ENV_CURVE[2*EG_ENT+1];
196 
197 /* multiple table */
198 #define ML 2
199 static const UINT32 MUL_TABLE[16]= {
200 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
201    0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
202    8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
203 };
204 #undef ML
205 
206 /* dummy attack / decay rate ( when rate == 0 ) */
207 static INT32 RATE_0[16]= {
208 	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
209 };
210 
211 /* -------------------- static state --------------------- */
212 
213 /* lock level of common table */
214 static int num_lock = 0;
215 
216 /* work table */
217 static void *cur_chip = NULL;	/* current chip point */
218 /* current chip state */
219 /* static OPLSAMPLE  *bufL,*bufR; */
220 static OPL_CH *S_CH;
221 static OPL_CH *E_CH;
222 OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
223 
224 static INT32 outd[1];
225 static INT32 ams;
226 static INT32 vib;
227 INT32  *ams_table;
228 INT32  *vib_table;
229 static INT32 amsIncr;
230 static INT32 vibIncr;
231 INT32 feedback2;		/* connect for SLOT 2 */
232 
233 /* log output level */
234 #define LOG_ERR  3      /* ERROR       */
235 #define LOG_WAR  2      /* WARNING     */
236 #define LOG_INF  1      /* INFORMATION */
237 
238 /* #define LOG_LEVEL LOG_INF */
239 #define LOG_LEVEL	LOG_ERR
240 
241 /* #define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x */
242 #define LOG(n,x)
243 
244 /* --------------------- subroutines  --------------------- */
245 #ifdef __clang__
Limit(int val,int max,int min)246 int Limit( int val, int max, int min ) {
247 #else
248 INLINE int Limit( int val, int max, int min ) {
249 #endif
250 	if ( val > max ) {
251 		val = max;
252 	} else if ( val < min ) {
253 		val = min;
254 	}
255 	return val;
256 }
257 
258 /* status set and IRQ handling */
259 #ifdef __clang__
260 void OPL_STATUS_SET(FM_OPL *OPL,int flag) {
261 #else
262 INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) {
263 #endif
264 	/* set status flag */
265 	OPL->status |= flag;
266 	if ( !(OPL->status & 0x80) ) {
267 		/* IRQ on */
268 		if ( OPL->status & OPL->statusmask ) {
269 			OPL->status |= 0x80;
270 			/* callback user interrupt handler (IRQ is OFF to ON) */
271 			if (OPL->IRQHandler) {
272 				(OPL->IRQHandler)(OPL->IRQParam,1);
273 			}
274 		}
275 	}
276 }
277 
278 /* status reset and IRQ handling */
279 #ifdef __clang__
280 void OPL_STATUS_RESET(FM_OPL *OPL,int flag) {
281 #else
282 INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) {
283 #endif
284 	/* reset status flag */
285 	OPL->status &=~flag;
286 	if ( (OPL->status & 0x80) ) {
287 		if ( !(OPL->status & OPL->statusmask) ) {
288 			OPL->status &= 0x7f;
289 			/* callback user interrupt handler (IRQ is ON to OFF) */
290 			if ( OPL->IRQHandler ) {
291 				(OPL->IRQHandler)(OPL->IRQParam,0);
292 			}
293 		}
294 	}
295 }
296 
297 /* IRQ mask set */
298 #ifdef __clang__
299 void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) {
300 #else
301 INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) {
302 #endif
303 	OPL->statusmask = flag;
304 	/* IRQ handling check */
305 	OPL_STATUS_SET(OPL,0);
306 	OPL_STATUS_RESET(OPL,0);
307 }
308 
309 /* ----- key on  ----- */
310 #ifdef __clang__
311 void OPL_KEYON(OPL_SLOT *SLOT) {
312 #else
313 INLINE void OPL_KEYON(OPL_SLOT *SLOT) {
314 #endif
315 	/* sin wave restart */
316 	SLOT->Cnt = 0;
317 	/* set attack */
318 	SLOT->evm = ENV_MOD_AR;
319 	SLOT->evs = SLOT->evsa;
320 	SLOT->evc = EG_AST;
321 	SLOT->eve = EG_AED;
322 }
323 /* ----- key off ----- */
324 #ifdef __clang__
325 void OPL_KEYOFF(OPL_SLOT *SLOT) {
326 #else
327 INLINE void OPL_KEYOFF(OPL_SLOT *SLOT) {
328 #endif
329 	if( SLOT->evm > ENV_MOD_RR) {
330 		/* set envelope counter from envleope output */
331 		SLOT->evm = ENV_MOD_RR;
332 		if( !(SLOT->evc&EG_DST) ) {
333 			/* SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST; */
334 			SLOT->evc = EG_DST;
335 		}
336 		SLOT->eve = EG_DED;
337 		SLOT->evs = SLOT->evsr;
338 	}
339 }
340 
341 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
342 /* return : envelope output */
343 #ifdef __clang__
344 UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT ) {
345 #else
346 INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT ) {
347 #endif
348 	/* calcrate envelope generator */
349 	if( (SLOT->evc+=SLOT->evs) >= SLOT->eve ) {
350 		switch( SLOT->evm ){
351 			case ENV_MOD_AR: /* ATTACK -> DECAY1 */
352 				/* next DR */
353 				SLOT->evm = ENV_MOD_DR;
354 				SLOT->evc = EG_DST;
355 				SLOT->eve = SLOT->SL;
356 				SLOT->evs = SLOT->evsd;
357 				break;
358 			case ENV_MOD_DR: /* DECAY -> SL or RR */
359 				SLOT->evc = SLOT->SL;
360 				SLOT->eve = EG_DED;
361 				if(SLOT->eg_typ)
362 				{
363 					SLOT->evs = 0;
364 				}
365 				else
366 				{
367 					SLOT->evm = ENV_MOD_RR;
368 					SLOT->evs = SLOT->evsr;
369 				}
370 				break;
371 			case ENV_MOD_RR: /* RR -> OFF */
372 				SLOT->evc = EG_OFF;
373 				SLOT->eve = EG_OFF+1;
374 				SLOT->evs = 0;
375 				break;
376 			}
377 	}
378 	/* calcrate envelope */
379 	return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
380 }
381 
382 /* set algorythm connection */
383 static void set_algorythm( OPL_CH *CH) {
384 	INT32 *carrier = &outd[0];
385 	CH->connect1 = CH->CON ? carrier : &feedback2;
386 	CH->connect2 = carrier;
387 }
388 
389 /* ---------- frequency counter for operater update ---------- */
390 #ifdef __clang__
391 void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) {
392 #else
393 INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) {
394 #endif
395 	int ksr;
396 
397 	/* frequency step counter */
398 	SLOT->Incr = CH->fc * SLOT->mul;
399 	ksr = CH->kcode >> SLOT->KSR;
400 
401 	if ( SLOT->ksr != ksr ) {
402 		SLOT->ksr = ksr;
403 		/* attack , decay rate recalcration */
404 		SLOT->evsa = SLOT->AR[ksr];
405 		SLOT->evsd = SLOT->DR[ksr];
406 		SLOT->evsr = SLOT->RR[ksr];
407 	}
408 	SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
409 }
410 
411 /* set multi,am,vib,EG-TYP,KSR,mul */
412 #ifdef __clang__
413 void set_mul(FM_OPL *OPL,int slot,int v) {
414 #else
415 INLINE void set_mul(FM_OPL *OPL,int slot,int v) {
416 #endif
417 
418 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
419 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
420 
421 	SLOT->mul    = MUL_TABLE[v&0x0f];
422 	SLOT->KSR    = (v&0x10) ? 0 : 2;
423 	SLOT->eg_typ = (v&0x20)>>5;
424 	SLOT->vib    = (v&0x40);
425 	SLOT->ams    = (v&0x80);
426 	CALC_FCSLOT(CH,SLOT);
427 }
428 
429 /* set ksl & tl */
430 #ifdef __clang__
431 void set_ksl_tl(FM_OPL *OPL,int slot,int v) {
432 #else
433 INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) {
434 #endif
435 
436 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
437 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
438 	int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
439 
440 	SLOT->ksl = ksl ? 3-ksl : 31;
441 	SLOT->TL  = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
442 
443 	if ( !(OPL->mode&0x80) ) {	/* not CSM latch total level */
444 		SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
445 	}
446 }
447 
448 /* set attack rate & decay rate  */
449 #ifdef __clang__
450 void set_ar_dr(FM_OPL *OPL,int slot,int v) {
451 #else
452 INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) {
453 #endif
454 
455 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
456 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
457 	int ar = v>>4;
458 	int dr = v&0x0f;
459 
460 	SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
461 	SLOT->evsa = SLOT->AR[SLOT->ksr];
462 	if ( SLOT->evm == ENV_MOD_AR ) {
463 		SLOT->evs = SLOT->evsa;
464 	}
465 
466 	SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
467 	SLOT->evsd = SLOT->DR[SLOT->ksr];
468 
469 	if ( SLOT->evm == ENV_MOD_DR ) {
470 		SLOT->evs = SLOT->evsd;
471 	}
472 }
473 
474 /* set sustain level & release rate */
475 #ifdef __clang__
476 void set_sl_rr(FM_OPL *OPL,int slot,int v) {
477 #else
478 INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) {
479 #endif
480 	OPL_CH   *CH   = &OPL->P_CH[slot/2];
481 	OPL_SLOT *SLOT = &CH->SLOT[slot&1];
482 	int sl = v>>4;
483 	int rr = v & 0x0f;
484 
485 	SLOT->SL = SL_TABLE[sl];
486 	if ( SLOT->evm == ENV_MOD_DR ) {
487 		SLOT->eve = SLOT->SL;
488 	}
489 	SLOT->RR = &OPL->DR_TABLE[rr<<2];
490 	SLOT->evsr = SLOT->RR[SLOT->ksr];
491 	if ( SLOT->evm == ENV_MOD_RR ) {
492 		SLOT->evs = SLOT->evsr;
493 	}
494 }
495 
496 /* operator output calcrator */
497 #define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
498 /* ---------- calcrate one of channel ---------- */
499 #ifdef __clang__
500 void OPL_CALC_CH( OPL_CH *CH ) {
501 #else
502 INLINE void OPL_CALC_CH( OPL_CH *CH ) {
503 #endif
504 	UINT32 env_out;
505 	OPL_SLOT *SLOT;
506 
507 	feedback2 = 0;
508 	/* SLOT 1 */
509 	SLOT = &CH->SLOT[SLOT1];
510 	env_out=OPL_CALC_SLOT(SLOT);
511 	if( env_out < EG_ENT-1 ) {
512 		/* PG */
513 		if (SLOT->vib) {
514 			SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
515 		} else {
516 			SLOT->Cnt += SLOT->Incr;
517 		}
518 		/* connectoion */
519 		if(CH->FB) {
520 			int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
521 			CH->op1_out[1] = CH->op1_out[0];
522 			*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
523 		} else {
524 			*CH->connect1 += OP_OUT(SLOT,env_out,0);
525 		}
526 	} else {
527 		CH->op1_out[1] = CH->op1_out[0];
528 		CH->op1_out[0] = 0;
529 	}
530 	/* SLOT 2 */
531 	SLOT = &CH->SLOT[SLOT2];
532 	env_out=OPL_CALC_SLOT(SLOT);
533 	if ( env_out < EG_ENT-1 ) {
534 		/* PG */
535 		if (SLOT->vib) {
536 			SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
537 		} else {
538 			SLOT->Cnt += SLOT->Incr;
539 		}
540 		/* connectoion */
541 		outd[0] += OP_OUT(SLOT,env_out, feedback2);
542 	}
543 }
544 
545 /* ---------- calcrate rythm block ---------- */
546 #define WHITE_NOISE_db 6.0
547 #ifdef __clang__
548 void OPL_CALC_RH( OPL_CH *CH ) {
549 #else
550 INLINE void OPL_CALC_RH( OPL_CH *CH ) {
551 #endif
552 	UINT32 env_tam,env_sd,env_top,env_hh;
553 	int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
554 	INT32 tone8;
555 
556 	OPL_SLOT *SLOT;
557 	int env_out;
558 
559 	/* BD : same as FM serial mode and output level is large */
560 	feedback2 = 0;
561 	/* SLOT 1 */
562 	SLOT = &CH[6].SLOT[SLOT1];
563 	env_out=OPL_CALC_SLOT(SLOT);
564 	if ( env_out < EG_ENT-1 ) {
565 		/* PG */
566 		if (SLOT->vib) {
567 			SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
568 		} else {
569 			SLOT->Cnt += SLOT->Incr;
570 		}
571 		/* connectoion */
572 		if(CH[6].FB) {
573 			int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
574 			CH[6].op1_out[1] = CH[6].op1_out[0];
575 			feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
576 		} else {
577 			feedback2 = OP_OUT(SLOT,env_out,0);
578 		}
579 	} else {
580 		feedback2 = 0;
581 		CH[6].op1_out[1] = CH[6].op1_out[0];
582 		CH[6].op1_out[0] = 0;
583 	}
584 	/* SLOT 2 */
585 	SLOT = &CH[6].SLOT[SLOT2];
586 	env_out=OPL_CALC_SLOT(SLOT);
587 	if( env_out < EG_ENT-1 ) {
588 		/* PG */
589 		if (SLOT->vib) {
590 			SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
591 		} else {
592 			SLOT->Cnt += SLOT->Incr;
593 		}
594 		/* connectoion */
595 		outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
596 	}
597 
598 	/* SD  (17) = mul14[fnum7] + white noise
599 	   TAM (15) = mul15[fnum8]
600 	   TOP (18) = fnum6(mul18[fnum8]+whitenoise)
601 	   HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise */
602 	env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
603 	env_tam=OPL_CALC_SLOT(SLOT8_1);
604 	env_top=OPL_CALC_SLOT(SLOT8_2);
605 	env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
606 
607 	/* PG */
608 	if(SLOT7_1->vib) {
609 		SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
610 	} else {
611 		SLOT7_1->Cnt += 2*SLOT7_1->Incr;
612 	}
613 	if (SLOT7_2->vib) {
614 		SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
615 	} else {
616 		SLOT7_2->Cnt += (CH[7].fc*8);
617 	}
618 	if (SLOT8_1->vib) {
619 		SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
620 	} else {
621 		SLOT8_1->Cnt += SLOT8_1->Incr;
622 	}
623 	if (SLOT8_2->vib) {
624 		SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
625 	}
626 	else {
627 		SLOT8_2->Cnt += (CH[8].fc*48);
628 	}
629 
630 	tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
631 
632 	/* SD */
633 	if( env_sd < EG_ENT-1 ) {
634 		outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
635 	}
636 	/* TAM */
637 	if( env_tam < EG_ENT-1 ) {
638 		outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
639 	}
640 	/* TOP-CY */
641 	if( env_top < EG_ENT-1 ) {
642 		outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
643 	}
644 	/* HH */
645 	if( env_hh  < EG_ENT-1 ) {
646 		outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
647 	}
648 }
649 
650 /* ----------- initialize time tabls ----------- */
651 static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE ) {
652 	int i;
653 	double rate;
654 
655 	/* make attack rate & decay rate tables */
656 	for ( i = 0; i < 4; i++ ) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
657 	for (i = 4; i <= 60; i++) {
658 		rate  = OPL->freqbase;						/* frequency rate */
659 		if( i < 60 ) {
660 			rate *= 1.0+(i&3)*0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
661 		}
662 		rate *= 1<<((i>>2)-1);						/* b2-5 : shift bit */
663 		rate *= (double)(EG_ENT<<ENV_BITS);
664 		OPL->AR_TABLE[i] = rate / ARRATE;
665 		OPL->DR_TABLE[i] = rate / DRRATE;
666 	}
667 	for ( i = 60; i < 75; i++ ) {
668 		OPL->AR_TABLE[i] = EG_AED-1;
669 		OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
670 	}
671 #if 0
672 			for ( i = 0; i < 64 ; i++ ) {	/* make for overflow area */
673 				LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
674 					((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
675 					((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
676 			}
677 #endif
678 }
679 
680 /* ---------- generic table initialize ---------- */
681 static int OPLOpenTable( void ) {
682 	int s,t;
683 	double rate;
684 	int i,j;
685 	double pom;
686 
687 	/* allocate dynamic tables */
688 	if ( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL ) {
689 		return 0;
690 	}
691 	if ( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL ) {
692 		free(TL_TABLE);
693 		return 0;
694 	}
695 	if ( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL ) {
696 		free(TL_TABLE);
697 		free(SIN_TABLE);
698 		return 0;
699 	}
700 	if ( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL ) {
701 		free(TL_TABLE);
702 		free(SIN_TABLE);
703 		free(AMS_TABLE);
704 		return 0;
705 	}
706 	/* make total level table */
707 	for ( t = 0; t < EG_ENT-1; t++ ) {
708 		rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);	/* dB -> voltage */
709 		TL_TABLE[       t] =  (int)rate;
710 		TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
711 /*		LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
712 	}
713 	/* fill volume off area */
714 	for ( t = EG_ENT-1; t < TL_MAX; t++) {
715 		TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
716 	}
717 
718 	/* make sinwave table (total level offet) */
719 	/* degree 0 = degree 180 = off */
720 	SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
721 	for ( s = 1; s <= SIN_ENT/4; s++) {
722 		pom = sin(2*PI*s/SIN_ENT); /* sin     */
723 		pom = 20*log10(1/pom);	   /* decibel */
724 		j = pom / EG_STEP;         /* TL_TABLE steps */
725 
726         /* degree 0   -  90    , degree 180 -  90 : plus section */
727 		SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
728         /* degree 180 - 270    , degree 360 - 270 : minus section */
729 		SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
730 /*		LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
731 	}
732 	for ( s = 0; s < SIN_ENT; s++) {
733 		SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
734 		SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
735 		SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
736 	}
737 
738 	/* envelope counter -> envelope output table */
739 	for ( i=0; i<EG_ENT; i++ ) {
740 		/* ATTACK curve */
741 		pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
742 		/* if( pom >= EG_ENT ) pom = EG_ENT-1; */
743 		ENV_CURVE[i] = (int)pom;
744 		/* DECAY ,RELEASE curve */
745 		ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
746 	}
747 	/* off */
748 	ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
749 	/* make LFO ams table */
750 	for ( i=0; i<AMS_ENT; i++ ) {
751 		pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
752 		AMS_TABLE[i]         = (1.0/EG_STEP)*pom; /* 1dB   */
753 		AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
754 	}
755 	/* make LFO vibrate table */
756 	for (i=0; i<VIB_ENT; i++) {
757 		/* 100cent = 1seminote = 6% ?? */
758 		pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
759 		VIB_TABLE[i]         = VIB_RATE + (pom*0.07); /* +- 7cent */
760 		VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
761 		/* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
762 	}
763 	return 1;
764 }
765 
766 
767 static void OPLCloseTable( void ) {
768 	free(TL_TABLE);
769 	free(SIN_TABLE);
770 	free(AMS_TABLE);
771 	free(VIB_TABLE);
772 }
773 
774 /* CSM Key Controll */
775 #ifdef __clang__
776 void CSMKeyControll(OPL_CH *CH) {
777 #else
778 INLINE void CSMKeyControll(OPL_CH *CH) {
779 #endif
780 	OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
781 	OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
782 	/* all key off */
783 	OPL_KEYOFF(slot1);
784 	OPL_KEYOFF(slot2);
785 	/* total level latch */
786 	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
787 	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
788 	/* key on */
789 	CH->op1_out[0] = CH->op1_out[1] = 0;
790 	OPL_KEYON(slot1);
791 	OPL_KEYON(slot2);
792 }
793 
794 /* ---------- opl initialize ---------- */
795 static void OPL_initalize(FM_OPL *OPL) {
796 	int fn;
797 
798 	/* frequency base */
799 	OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72  : 0;
800 	/* Timer base time */
801 	OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
802 	/* make time tables */
803 	init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
804 	/* make fnumber -> increment counter table */
805 	for( fn=0 ; fn < 1024 ; fn++ ) {
806 		OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
807 	}
808 	/* LFO freq.table */
809 	OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
810 	OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
811 }
812 
813 /* ---------- write a OPL registers ---------- */
814 static void OPLWriteReg(FM_OPL *OPL, int r, int v) {
815 	OPL_CH *CH;
816 	int slot;
817 	int block_fnum;
818 
819 	switch ( r&0xe0 ) {
820 	case 0x00: /* 00-1f:controll */
821 		switch ( r&0x1f ) {
822 			case 0x01:
823 				/* wave selector enable */
824 				if(OPL->type&OPL_TYPE_WAVESEL)
825 				{
826 					OPL->wavesel = v&0x20;
827 					if( !OPL->wavesel )
828 					{
829 						/* preset compatible mode */
830 						int c;
831 						for ( c=0; c<OPL->max_ch; c++ )
832 						{
833 							OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
834 							OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
835 						}
836 					}
837 				}
838 				return;
839 			case 0x02:	/* Timer 1 */
840 				OPL->T[0] = (256-v)*4;
841 				break;
842 			case 0x03:	/* Timer 2 */
843 				OPL->T[1] = (256-v)*16;
844 				return;
845 			case 0x04:	/* IRQ clear / mask and Timer enable */
846 				if ( v&0x80 ) {	/* IRQ flag clear */
847 					OPL_STATUS_RESET(OPL,0x7f);
848 				}
849 				else {	/* set IRQ mask ,timer enable*/
850 					UINT8 st1 = v&1;
851 					UINT8 st2 = (v>>1)&1;
852 					/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
853 					OPL_STATUS_RESET(OPL,v&0x78);
854 					OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
855 					/* timer 2 */
856 					if ( OPL->st[1] != st2 ) {
857 						double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
858 						OPL->st[1] = st2;
859 						if ( OPL->TimerHandler ) {
860 							(OPL->TimerHandler)(OPL->TimerParam+1,interval);
861 						}
862 					}
863 					/* timer 1 */
864 					if ( OPL->st[0] != st1 ) {
865 						double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
866 						OPL->st[0] = st1;
867 						if ( OPL->TimerHandler ) {
868 							(OPL->TimerHandler)(OPL->TimerParam+0,interval);
869 						}
870 					}
871 				}
872 				return;
873 #if BUILD_Y8950
874 			case 0x06:		/* Key Board OUT */
875 				if ( OPL->type&OPL_TYPE_KEYBOARD ) {
876 					if ( OPL->keyboardhandler_w ) {
877 						OPL->keyboardhandler_w(OPL->keyboard_param,v);
878 					}
879 					else {
880 						LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
881 					}
882 				}
883 				return;
884 			case 0x07:	/* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
885 				if ( OPL->type&OPL_TYPE_ADPCM ) {
886 					YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
887 				}
888 				return;
889 			case 0x08:	/* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
890 				OPL->mode = v;
891 				v&=0x1f;	/* for DELTA-T unit */
892 			case 0x09:		/* START ADD */
893 			case 0x0a:
894 			case 0x0b:		/* STOP ADD  */
895 			case 0x0c:
896 			case 0x0d:		/* PRESCALE   */
897 			case 0x0e:
898 			case 0x0f:		/* ADPCM data */
899 			case 0x10: 		/* DELTA-N    */
900 			case 0x11: 		/* DELTA-N    */
901 			case 0x12: 		/* EG-CTRL    */
902 				if ( OPL->type&OPL_TYPE_ADPCM ) {
903 					YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
904 				}
905 				return;
906 #if 0
907 			case 0x15:		/* DAC data    */
908 			case 0x16:
909 			case 0x17:		/* SHIFT    */
910 				return;
911 			case 0x18:		/* I/O CTRL (Direction) */
912 				if ( OPL->type&OPL_TYPE_IO ) {
913 					OPL->portDirection = v&0x0f;
914 				}
915 				return;
916 			case 0x19:		/* I/O DATA */
917 				if ( OPL->type&OPL_TYPE_IO ) {
918 					OPL->portLatch = v;
919 					if ( OPL->porthandler_w ) {
920 						OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
921 					}
922 				}
923 				return;
924 			case 0x1a:		/* PCM data */
925 				return;
926 #endif
927 #endif
928 		}
929 		break;
930 	case 0x20:	/* am,vib,ksr,eg type,mul */
931 		slot = slot_array[r&0x1f];
932 		if ( slot == -1 ) {
933 			return;
934 		}
935 		set_mul(OPL,slot,v);
936 		return;
937 	case 0x40:
938 		slot = slot_array[r&0x1f];
939 		if ( slot == -1 ) {
940 			return;
941 		}
942 		set_ksl_tl(OPL,slot,v);
943 		return;
944 	case 0x60:
945 		slot = slot_array[r&0x1f];
946 		if ( slot == -1 ) {
947 			return;
948 		}
949 		set_ar_dr(OPL,slot,v);
950 		return;
951 	case 0x80:
952 		slot = slot_array[r&0x1f];
953 		if ( slot == -1 ) {
954 			return;
955 		}
956 		set_sl_rr(OPL,slot,v);
957 		return;
958 	case 0xa0:
959 		switch ( r ) {
960 			/* amsep,vibdep,r,bd,sd,tom,tc,hh */
961 			case 0xbd: {
962 				UINT8 rkey = OPL->rythm^v;
963 				OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
964 				OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
965 				OPL->rythm  = v&0x3f;
966 				if(OPL->rythm&0x20) {
967 #if 0
968 					usrintf_showmessage("OPL Rythm mode select");
969 #endif
970 					/* BD key on/off */
971 					if ( rkey&0x10 ) {
972 						if ( v&0x10 ) {
973 							OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
974 							OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
975 							OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
976 						} else {
977 							OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
978 							OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
979 						}
980 					}
981 					/* SD key on/off */
982 					if ( rkey&0x08 ) {
983 						if ( v&0x08 ) {
984 							OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
985 						} else {
986 							OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
987 						}
988 					}/* TAM key on/off */
989 					if ( rkey&0x04 ) {
990 						if ( v&0x04 ) {
991 							OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
992 						} else {
993 							OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
994 						}
995 					}
996 					/* TOP-CY key on/off */
997 					if ( rkey&0x02 ) {
998 						if ( v&0x02 ) {
999 							OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
1000 						} else {
1001 							OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
1002 						}
1003 					}
1004 					/* HH key on/off */
1005 					if ( rkey&0x01 ) {
1006 						if ( v&0x01 ) {
1007 							OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
1008 						}
1009 						else {
1010 							OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
1011 						}
1012 					}
1013 				}
1014 			}
1015 			return;
1016 		}
1017 		/* keyon,block,fnum */
1018 		if ( (r&0x0f) > 8 ) {
1019 			return;
1020 		}
1021 		CH = &OPL->P_CH[r&0x0f];
1022 		/* a0-a8 */
1023 		if ( !(r&0x10) ) {
1024 			block_fnum  = (CH->block_fnum&0x1f00) | v;
1025 		}
1026 		/* b0-b8 */
1027 		else {
1028 			int keyon = (v>>5)&1;
1029 			block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
1030 			if ( CH->keyon != keyon ) {
1031 				if ( (CH->keyon=keyon) ) {
1032 					CH->op1_out[0] = CH->op1_out[1] = 0;
1033 					OPL_KEYON(&CH->SLOT[SLOT1]);
1034 					OPL_KEYON(&CH->SLOT[SLOT2]);
1035 				} else {
1036 					OPL_KEYOFF(&CH->SLOT[SLOT1]);
1037 					OPL_KEYOFF(&CH->SLOT[SLOT2]);
1038 				}
1039 			}
1040 		}
1041 		/* update */
1042 		if(CH->block_fnum != block_fnum) {
1043 			int blockRv = 7-(block_fnum>>10);
1044 			int fnum   = block_fnum&0x3ff;
1045 			CH->block_fnum = block_fnum;
1046 
1047 			CH->ksl_base = KSL_TABLE[block_fnum>>6];
1048 			CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
1049 			CH->kcode = CH->block_fnum>>9;
1050 			if ( (OPL->mode&0x40) && CH->block_fnum&0x100 ) {
1051 				CH->kcode |=1;
1052 			}
1053 			CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
1054 			CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
1055 		}
1056 		return;
1057 	case 0xc0:
1058 		/* FB,C */
1059 		if ( (r&0x0f) > 8 ) {
1060 			return;
1061 		}
1062 		CH = &OPL->P_CH[r&0x0f];
1063 		//{
1064 		int feedback = (v>>1)&7;
1065 		CH->FB   = feedback ? (8+1) - feedback : 0;
1066 		CH->CON = v&1;
1067 		set_algorythm(CH);
1068 		//}
1069 		return;
1070 	case 0xe0: /* wave type */
1071 		slot = slot_array[r&0x1f];
1072 		if ( slot == -1 ) {
1073 			return;
1074 		}
1075 		CH = &OPL->P_CH[slot/2];
1076 		if (OPL->wavesel) {
1077 			/* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
1078 			CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
1079 		}
1080 		return;
1081 	}
1082 }
1083 
1084 /* lock/unlock for common table */
1085 static int OPL_LockTable(void) {
1086 	num_lock++;
1087 	if ( num_lock>1 ) {
1088 		return 0;
1089 	}
1090 	/* first time */
1091 	cur_chip = NULL;
1092 	/* allocate total level table (128kb space) */
1093 	if ( !OPLOpenTable() ) {
1094 		num_lock--;
1095 		return -1;
1096 	}
1097 	return 0;
1098 }
1099 
1100 static void OPL_UnLockTable(void) {
1101 	if(num_lock) {
1102 		num_lock--;
1103 	}
1104 	if(num_lock) {
1105 		return;
1106 	}
1107 	/* last time */
1108 	cur_chip = NULL;
1109 	OPLCloseTable();
1110 }
1111 
1112 #if (BUILD_YM3812 || BUILD_YM3526)
1113 /*******************************************************************************/
1114 /*		YM3812 local section                                                   */
1115 /*******************************************************************************/
1116 
1117 /* ---------- update one of chip ----------- */
1118 void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) {
1119     int i;
1120 	int data;
1121 	OPLSAMPLE *buf = buffer;
1122 	UINT32 amsCnt  = OPL->amsCnt;
1123 	UINT32 vibCnt  = OPL->vibCnt;
1124 	UINT8 rythm = OPL->rythm&0x20;
1125 	OPL_CH *CH,*R_CH;
1126 
1127 	if ( (void *)OPL != cur_chip ) {
1128 		cur_chip = (void *)OPL;
1129 		/* channel pointers */
1130 		S_CH = OPL->P_CH;
1131 		E_CH = &S_CH[9];
1132 		/* rythm slot */
1133 		SLOT7_1 = &S_CH[7].SLOT[SLOT1];
1134 		SLOT7_2 = &S_CH[7].SLOT[SLOT2];
1135 		SLOT8_1 = &S_CH[8].SLOT[SLOT1];
1136 		SLOT8_2 = &S_CH[8].SLOT[SLOT2];
1137 		/* LFO state */
1138 		amsIncr = OPL->amsIncr;
1139 		vibIncr = OPL->vibIncr;
1140 		ams_table = OPL->ams_table;
1141 		vib_table = OPL->vib_table;
1142 	}
1143 	R_CH = rythm ? &S_CH[6] : E_CH;
1144     for ( i=0; i < length ; i++ ) {
1145 		/*            channel A         channel B         channel C      */
1146 		/* LFO */
1147 		ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
1148 		vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
1149 		outd[0] = 0;
1150 		/* FM part */
1151 		for(CH=S_CH ; CH < R_CH ; CH++)
1152 			OPL_CALC_CH(CH);
1153 		/* Rythn part */
1154 		if(rythm)
1155 			OPL_CALC_RH(S_CH);
1156 		/* limit check */
1157 		data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
1158 		/* store to sound buffer */
1159 		buf[i] = data >> OPL_OUTSB;
1160 	}
1161 
1162 	OPL->amsCnt = amsCnt;
1163 	OPL->vibCnt = vibCnt;
1164 #ifdef OPL_OUTPUT_LOG
1165 	if(opl_dbg_fp) {
1166 		for ( opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++ ) {
1167 			if ( opl_dbg_opl[opl_dbg_chip] == OPL ) {
1168 				break;
1169 			}
1170 		}
1171 		fprintf(opl_dbg_fp, "%c%c%c", 0x20+opl_dbg_chip, length&0xff, length/256);
1172 	}
1173 #endif
1174 }
1175 #endif /* (BUILD_YM3812 || BUILD_YM3526) */
1176 
1177 #if BUILD_Y8950
1178 
1179 void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) {
1180     int i;
1181 	int data;
1182 	OPLSAMPLE *buf = buffer;
1183 	UINT32 amsCnt  = OPL->amsCnt;
1184 	UINT32 vibCnt  = OPL->vibCnt;
1185 	UINT8 rythm = OPL->rythm&0x20;
1186 	OPL_CH *CH,*R_CH;
1187 	YM_DELTAT *DELTAT = OPL->deltat;
1188 
1189 	/* setup DELTA-T unit */
1190 	YM_DELTAT_DECODE_PRESET(DELTAT);
1191 
1192 	if ( (void *)OPL != cur_chip ) {
1193 		cur_chip = (void *)OPL;
1194 		/* channel pointers */
1195 		S_CH = OPL->P_CH;
1196 		E_CH = &S_CH[9];
1197 		/* rythm slot */
1198 		SLOT7_1 = &S_CH[7].SLOT[SLOT1];
1199 		SLOT7_2 = &S_CH[7].SLOT[SLOT2];
1200 		SLOT8_1 = &S_CH[8].SLOT[SLOT1];
1201 		SLOT8_2 = &S_CH[8].SLOT[SLOT2];
1202 		/* LFO state */
1203 		amsIncr = OPL->amsIncr;
1204 		vibIncr = OPL->vibIncr;
1205 		ams_table = OPL->ams_table;
1206 		vib_table = OPL->vib_table;
1207 	}
1208 	R_CH = rythm ? &S_CH[6] : E_CH;
1209     for ( i=0; i < length ; i++ ) {
1210 		/*            channel A         channel B         channel C      */
1211 		/* LFO */
1212 		ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
1213 		vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
1214 		outd[0] = 0;
1215 		/* deltaT ADPCM */
1216 		if( DELTAT->portstate ) {
1217 			YM_DELTAT_ADPCM_CALC(DELTAT);
1218 		}
1219 		/* FM part */
1220 		for ( CH=S_CH ; CH < R_CH ; CH++ ) {
1221 			OPL_CALC_CH(CH);
1222 		}
1223 		/* Rythn part */
1224 		if ( rythm ) {
1225 			OPL_CALC_RH(S_CH);
1226 		}
1227 		/* limit check */
1228 		data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
1229 		/* store to sound buffer */
1230 		buf[i] = data >> OPL_OUTSB;
1231 	}
1232 	OPL->amsCnt = amsCnt;
1233 	OPL->vibCnt = vibCnt;
1234 	/* deltaT START flag */
1235 	if ( !DELTAT->portstate ) {
1236 		OPL->status &= 0xfe;
1237 	}
1238 }
1239 #endif
1240 
1241 /* ---------- reset one of chip ---------- */
1242 void OPLResetChip(FM_OPL *OPL) {
1243 	int c,s;
1244 	int i;
1245 
1246 	/* reset chip */
1247 	OPL->mode   = 0;	/* normal mode */
1248 	OPL_STATUS_RESET(OPL,0x7f);
1249 	/* reset with register write */
1250 	OPLWriteReg(OPL,0x01,0); /* wabesel disable */
1251 	OPLWriteReg(OPL,0x02,0); /* Timer1 */
1252 	OPLWriteReg(OPL,0x03,0); /* Timer2 */
1253 	OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
1254 	for ( i = 0xff ; i >= 0x20 ; i-- ) {
1255 		OPLWriteReg(OPL,i,0);
1256 	}
1257 	/* reset OPerator paramater */
1258 	for ( c = 0 ; c < OPL->max_ch ; c++ ) {
1259 		OPL_CH *CH = &OPL->P_CH[c];
1260 		/* OPL->P_CH[c].PAN = OPN_CENTER; */
1261 		for ( s = 0 ; s < 2 ; s++ ) {
1262 			/* wave table */
1263 			CH->SLOT[s].wavetable = &SIN_TABLE[0];
1264 			/* CH->SLOT[s].evm = ENV_MOD_RR; */
1265 			CH->SLOT[s].evc = EG_OFF;
1266 			CH->SLOT[s].eve = EG_OFF+1;
1267 			CH->SLOT[s].evs = 0;
1268 		}
1269 	}
1270 #if BUILD_Y8950
1271 	if ( OPL->type&OPL_TYPE_ADPCM ) {
1272 		YM_DELTAT *DELTAT = OPL->deltat;
1273 
1274 		DELTAT->freqbase = OPL->freqbase;
1275 		DELTAT->output_pointer = outd;
1276 		DELTAT->portshift = 5;
1277 		DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
1278 		YM_DELTAT_ADPCM_Reset(DELTAT,0);
1279 	}
1280 #endif
1281 }
1282 
1283 /* ----------  Create one of vietual YM3812 ----------       */
1284 /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
1285 FM_OPL *OPLCreate(int type, int clock, int rate) {
1286 	char *ptr;
1287 	FM_OPL *OPL;
1288 	int state_size;
1289 	int max_ch = 9; /* normaly 9 channels */
1290 
1291 	if ( OPL_LockTable() ==-1 ) {
1292 		return NULL;
1293 	}
1294 	/* allocate OPL state space */
1295 	state_size  = sizeof(FM_OPL);
1296 	state_size += sizeof(OPL_CH)*max_ch;
1297 #if BUILD_Y8950
1298 	if ( type&OPL_TYPE_ADPCM ) {
1299 		state_size+= sizeof(YM_DELTAT);
1300 	}
1301 #endif
1302 	/* allocate memory block */
1303 	ptr = malloc(state_size);
1304 	if (ptr==NULL) {
1305 		return NULL;
1306 	}
1307 	/* clear */
1308 	memset(ptr,0,state_size);
1309 	OPL        = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
1310 	OPL->P_CH  = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
1311 #if BUILD_Y8950
1312 	if ( type&OPL_TYPE_ADPCM ) {
1313 		OPL->deltat = (YM_DELTAT *)ptr;
1314 		ptr+=sizeof(YM_DELTAT);
1315 	}
1316 #endif
1317 	/* set channel state pointer */
1318 	OPL->type  = type;
1319 	OPL->clock = clock;
1320 	OPL->rate  = rate;
1321 	OPL->max_ch = max_ch;
1322 	/* init grobal tables */
1323 	OPL_initalize(OPL);
1324 	/* reset chip */
1325 	OPLResetChip(OPL);
1326 #ifdef OPL_OUTPUT_LOG
1327 	if (!opl_dbg_fp) {
1328 		opl_dbg_fp = fopen("opllog.opl","wb");
1329 		opl_dbg_maxchip = 0;
1330 	}
1331 	if (opl_dbg_fp) {
1332 		opl_dbg_opl[opl_dbg_maxchip] = OPL;
1333 		fprintf(opl_dbg_fp, "%c%c%c%c%c%c", 0x00+opl_dbg_maxchip,
1334 			type,
1335 			clock&0xff,
1336 			(clock/0x100)&0xff,
1337 			(clock/0x10000)&0xff,
1338 			(clock/0x1000000)&0xff);
1339 		opl_dbg_maxchip++;
1340 	}
1341 #endif
1342 	return OPL;
1343 }
1344 
1345 /* ----------  Destroy one of vietual YM3812 ----------       */
1346 void OPLDestroy(FM_OPL *OPL) {
1347 #ifdef OPL_OUTPUT_LOG
1348 	if(opl_dbg_fp) {
1349 		fclose(opl_dbg_fp);
1350 		opl_dbg_fp = NULL;
1351 	}
1352 #endif
1353 	OPL_UnLockTable();
1354 	free(OPL);
1355 }
1356 
1357 /* ----------  Option handlers ----------       */
1358 
1359 void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) {
1360 	OPL->TimerHandler   = TimerHandler;
1361 	OPL->TimerParam = channelOffset;
1362 }
1363 void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) {
1364 	OPL->IRQHandler     = IRQHandler;
1365 	OPL->IRQParam = param;
1366 }
1367 void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) {
1368 	OPL->UpdateHandler = UpdateHandler;
1369 	OPL->UpdateParam = param;
1370 }
1371 #if BUILD_Y8950
1372 void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) {
1373 	OPL->porthandler_w = PortHandler_w;
1374 	OPL->porthandler_r = PortHandler_r;
1375 	OPL->port_param = param;
1376 }
1377 
1378 void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) {
1379 	OPL->keyboardhandler_w = KeyboardHandler_w;
1380 	OPL->keyboardhandler_r = KeyboardHandler_r;
1381 	OPL->keyboard_param = param;
1382 }
1383 #endif
1384 /* ---------- YM3812 I/O interface ---------- */
1385 int OPLWrite(FM_OPL *OPL,int a,int v) {
1386 	if ( !(a&1) ) {	/* address port */
1387 		OPL->address = v & 0xff;
1388 	} else {	/* data port */
1389 		if ( OPL->UpdateHandler ) {
1390 			OPL->UpdateHandler(OPL->UpdateParam,0);
1391 		}
1392 #ifdef OPL_OUTPUT_LOG
1393 		if ( opl_dbg_fp ) {
1394 			for ( opl_dbg_chip=0; opl_dbg_chip<opl_dbg_maxchip; opl_dbg_chip++ ) {
1395 				if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
1396 			}
1397 			fprintf(opl_dbg_fp, "%c%c%c", 0x10+opl_dbg_chip, OPL->address, v);
1398 		}
1399 #endif
1400 		OPLWriteReg(OPL,OPL->address,v);
1401 	}
1402 	return OPL->status>>7;
1403 }
1404 
1405 unsigned char OPLRead(FM_OPL *OPL,int a) {
1406 	/* status port */
1407 	if( !(a&1) ) {
1408 		return OPL->status & (OPL->statusmask|0x80);
1409 	}
1410 
1411 	/* data port */
1412 	switch(OPL->address) {
1413 		case 0x05: /* KeyBoard IN */
1414 			if ( OPL->type&OPL_TYPE_KEYBOARD ) {
1415 				if ( OPL->keyboardhandler_r ) {
1416 					return OPL->keyboardhandler_r(OPL->keyboard_param);
1417 				} else {
1418 					LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
1419 				}
1420 			}
1421 			return 0;
1422 	#if 0
1423 		case 0x0f: /* ADPCM-DATA  */
1424 			return 0;
1425 	#endif
1426 		case 0x19: /* I/O DATA    */
1427 			if ( OPL->type&OPL_TYPE_IO ) {
1428 				if ( OPL->porthandler_r ) {
1429 					return OPL->porthandler_r(OPL->port_param);
1430 				}
1431 				else {
1432 					LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
1433 				}
1434 			}
1435 			return 0;
1436 		case 0x1a: /* PCM-DATA    */
1437 			return 0;
1438 	}
1439 	return 0;
1440 }
1441 
1442 int OPLTimerOver(FM_OPL *OPL,int c) {
1443 	/* Timer B */
1444 	if( c ) {
1445 		OPL_STATUS_SET(OPL,0x20);
1446 	}
1447 	/* Timer A */
1448 	else {
1449 		OPL_STATUS_SET(OPL,0x40);
1450 		/* CSM mode key,TL control */
1451 		/* CSM mode total level latch and auto key on */
1452 		if( OPL->mode & 0x80 ) {
1453 			int ch;
1454 			if (OPL->UpdateHandler) {
1455 				OPL->UpdateHandler(OPL->UpdateParam,0);
1456 			}
1457 			for ( ch=0; ch<9; ch++ ) {
1458 				CSMKeyControll( &OPL->P_CH[ch] );
1459 			}
1460 		}
1461 	}
1462 	/* reload timer */
1463 	if ( OPL->TimerHandler ) {
1464 		(OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
1465 	}
1466 	return OPL->status>>7;
1467 }
1468