1 #define YM2610B_WARNING
2 
3 /* YM2608 rhythm data is PCM ,not an ADPCM */
4 #define YM2608_RHYTHM_PCM
5 
6 /*
7 **
8 ** File: fm.c -- software implementation of FM sound generator
9 **
10 ** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
11 **
12 ** Version 0.37
13 **
14 */
15 
16 /*
17 **** change log. (hiro-shi) ****
18 ** 08-12-98:
19 ** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA
20 ** move ROM limit check.(CALC_CH? -> 2610Write1/2)
21 ** test program (ADPCMB_TEST)
22 ** move ADPCM A/B end check.
23 ** ADPCMB repeat flag(no check)
24 ** change ADPCM volume rate (8->16) (32->48).
25 **
26 ** 09-12-98:
27 ** change ADPCM volume. (8->16, 48->64)
28 ** replace ym2610 ch0/3 (YM-2610B)
29 ** init cur_chip (restart bug fix)
30 ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
31 ** add ADPCM_SHIFT_MASK
32 ** change ADPCMA_DECODE_MIN/MAX.
33 */
34 
35 /*
36     no check:
37 		YM2608 rhythm sound
38 		OPN SSG type envelope (SEG)
39 		YM2151 CSM speech mode
40 
41 	no support:
42 		status BUSY flag (everytime not busy)
43 		YM2608 status mask (register :0x110)
44 		YM2608 RYTHM sound
45 		YM2608 PCM memory data access , DELTA-T-ADPCM with PCM port
46 		YM2151 CSM speech mode with internal timer
47 
48 	preliminary :
49 		key scale level rate (?)
50 		attack rate time rate , curve
51 		decay  rate time rate , curve
52 		self-feedback algorythm
53 		YM2610 ADPCM-A mixing level , decode algorythm
54 		YM2151 noise mode (CH7.OP4)
55 		LFO contoller (YM2612/YM2610/YM2608/YM2151)
56 
57 	note:
58                         OPN                           OPM
59 		fnum          fM * 2^20 / (fM/(12*n))
60 		TimerOverA    ( 12*n)*(1024-NA)/fM        64*(1024-Na)/fM
61 		TimerOverB    (192*n)*(256-NB)/fM       1024*(256-Nb)/fM
62 		output bits   10bit<<3bit               16bit * 2ch (YM3012=10bit<<3bit)
63 		sampling rate fFM / (12*priscaler)      fM / 64
64 		lfo freq                                ( fM*2^(LFRQ/16) ) / (4295*10^6)
65 */
66 
67 /************************************************************************/
68 /*    comment of hiro-shi(Hiromitsu Shioya)                             */
69 /*    YM2610(B) = (OPN-B                                                */
70 /*    YM2610  : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */
71 /*    YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */
72 /************************************************************************/
73 
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <string.h>
77 #include <stdarg.h>
78 #include <math.h>
79 #ifndef __RAINE__
80 #include "driver.h"		/* use M.A.M.E. */
81 #else
82 #include "deftypes.h"		/* use RAINE */
83 #include "support.h"		/* use RAINE */
84 #endif
85 #include "ay8910.h"
86 #include "fm.h"
87 #include "osinline.h"
88 
89 #ifndef PI
90 #define PI 3.14159265358979323846
91 #endif
92 
93 /***** shared function building option ****/
94 #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2612)
95 #define BUILD_OPNB (BUILD_YM2610||BUILD_YM2610B)
96 #define BUILD_FM_ADPCMA (BUILD_YM2608||BUILD_OPNB)
97 #define BUILD_FM_ADPCMB (BUILD_YM2608||BUILD_OPNB)
98 #define BUILD_STEREO (BUILD_YM2608||BUILD_YM2610||BUILD_YM2612||BUILD_YM2151)
99 #define BUILD_LFO (BUILD_YM2608||BUILD_YM2610||BUILD_YM2612||BUILD_YM2151)
100 
101 #if BUILD_FM_ADPCMB
102 /* include external DELTA-T ADPCM unit */
103   #include "ymdeltat.h"		/* DELTA-T ADPCM UNIT */
104   #define DELTAT_MIXING_LEVEL (4) /* DELTA-T ADPCM MIXING LEVEL */
105 #endif
106 
107 #ifdef MAME_FASTSOUND
108 extern int fast_sound;
109 #endif
110 
111 /* -------------------- sound quality define selection --------------------- */
112 /* sinwave entries */
113 /* used static memory = SIN_ENT * 4 (byte) */
114 #define SIN_ENT 2048
115 
116 /* lower bits of envelope counter */
117 #define ENV_BITS 16
118 
119 /* envelope output entries */
120 #define EG_ENT   4096
121 #define EG_STEP (96.0/EG_ENT) /* OPL == 0.1875 dB */
122 
123 #if FM_LFO_SUPPORT
124 /* LFO table entries */
125 #define LFO_ENT 512
126 #define LFO_SHIFT (32-9)
127 #define LFO_RATE 0x10000
128 #endif
129 
130 /* -------------------- preliminary define section --------------------- */
131 /* attack/decay rate time rate */
132 #define OPM_ARRATE     399128
133 #define OPM_DRRATE    5514396
134 /* It is not checked , because I haven't YM2203 rate */
135 #define OPN_ARRATE  OPM_ARRATE
136 #define OPN_DRRATE  OPM_DRRATE
137 
138 /* PG output cut off level : 78dB(14bit)? */
139 #define PG_CUT_OFF ((int)(78.0/EG_STEP))
140 /* EG output cut off level : 68dB? */
141 #define EG_CUT_OFF ((int)(68.0/EG_STEP))
142 
143 #define FREQ_BITS 24		/* frequency turn          */
144 
145 /* PG counter is 21bits @oct.7 */
146 #define FREQ_RATE   (1<<(FREQ_BITS-21))
147 #define TL_BITS    (FREQ_BITS+2)
148 /* OPbit = 14(13+sign) : TL_BITS+1(sign) / output = 16bit */
149 #define TL_SHIFT (TL_BITS+1-(14-16))
150 
151 /* output final shift */
152 #define FM_OUTSB  (TL_SHIFT-FM_OUTPUT_BIT)
153 #define FM_MAXOUT ((1<<(TL_SHIFT-1))-1)
154 #define FM_MINOUT (-(1<<(TL_SHIFT-1)))
155 
156 /* -------------------- local defines , macros --------------------- */
157 
158 /* envelope counter position */
159 #define EG_AST   0					/* start of Attack phase */
160 #define EG_AED   (EG_ENT<<ENV_BITS)	/* end   of Attack phase */
161 #define EG_DST   EG_AED				/* start of Decay/Sustain/Release phase */
162 #define EG_DED   (EG_DST+(EG_ENT<<ENV_BITS)-1)	/* end   of Decay/Sustain/Release phase */
163 #define EG_OFF   EG_DED				/* off */
164 #if FM_SEG_SUPPORT
165 #define EG_UST   ((2*EG_ENT)<<ENV_BITS)  /* start of SEG UPSISE */
166 #define EG_UED   ((3*EG_ENT)<<ENV_BITS)  /* end of SEG UPSISE */
167 #endif
168 
169 /* register number to channel number , slot offset */
170 #define OPN_CHAN(N) (N&3)
171 #define OPN_SLOT(N) ((N>>2)&3)
172 #define OPM_CHAN(N) (N&7)
173 #define OPM_SLOT(N) ((N>>3)&3)
174 /* slot number */
175 #define SLOT1 0
176 #define SLOT2 2
177 #define SLOT3 1
178 #define SLOT4 3
179 
180 /* bit0 = Right enable , bit1 = Left enable */
181 #define OUTD_RIGHT  1
182 #define OUTD_LEFT   2
183 #define OUTD_CENTER 3
184 
185 /* FM timer model */
186 #define FM_TIMER_SINGLE (0)
187 #define FM_TIMER_INTERVAL (1)
188 
189 /* ---------- OPN / OPM one channel  ---------- */
190 typedef struct fm_slot {
191 	INT32 *DT;			/* detune          :DT_TABLE[DT]       */
192 	int DT2;			/* multiple,Detune2:(DT2<<4)|ML for OPM*/
193 	int TL;				/* total level     :TL << 8            */
194 	UINT8 KSR;			/* key scale rate  :3-KSR              */
195 	const INT32 *AR;	/* attack rate     :&AR_TABLE[AR<<1]   */
196 	const INT32 *DR;	/* decay rate      :&DR_TABLE[DR<<1]   */
197 	const INT32 *SR;	/* sustin rate     :&DR_TABLE[SR<<1]   */
198 	int   SL;			/* sustin level    :SL_TABLE[SL]       */
199 	const INT32 *RR;	/* release rate    :&DR_TABLE[RR<<2+2] */
200 	UINT8 SEG;			/* SSG EG type     :SSGEG              */
201 	UINT8 ksr;			/* key scale rate  :kcode>>(3-KSR)     */
202 	UINT32 mul;			/* multiple        :ML_TABLE[ML]       */
203 	/* Phase Generator */
204 	UINT32 Cnt;			/* frequency count :                   */
205 	UINT32 Incr;		/* frequency step  :                   */
206 	/* Envelope Generator */
207 	void (*eg_next)(struct fm_slot *SLOT);	/* pointer of phase handler */
208 	INT32 evc;			/* envelope counter                    */
209 	INT32 eve;			/* envelope counter end point          */
210 	INT32 evs;			/* envelope counter step               */
211 	INT32 evsa;			/* envelope step for Attack            */
212 	INT32 evsd;			/* envelope step for Decay             */
213 	INT32 evss;			/* envelope step for Sustain           */
214 	INT32 evsr;			/* envelope step for Release           */
215 	INT32 TLL;			/* adjusted TotalLevel                 */
216 	/* LFO */
217 	UINT8 amon;			/* AMS enable flag              */
218 	UINT32 ams;			/* AMS depth level of this SLOT */
219 }FM_SLOT;
220 
221 typedef struct fm_chan {
222 	FM_SLOT	SLOT[4];
223 	UINT8 PAN;			/* PAN :NONE,LEFT,RIGHT or CENTER */
224 	UINT8 ALGO;			/* Algorythm                      */
225 	UINT8 FB;			/* shift count of self feed back  */
226 	INT32 op1_out[2];	/* op1 output for beedback        */
227 	/* Algorythm (connection) */
228 	INT32 *connect1;		/* pointer of SLOT1 output    */
229 	INT32 *connect2;		/* pointer of SLOT2 output    */
230 	INT32 *connect3;		/* pointer of SLOT3 output    */
231 	INT32 *connect4;		/* pointer of SLOT4 output    */
232 	/* LFO */
233 	INT32 pms;				/* PMS depth level of channel */
234 	UINT32 ams;				/* AMS depth level of channel */
235 	/* Phase Generator */
236 	UINT32 fc;			/* fnum,blk    :adjusted to sampling rate */
237 	UINT8 fn_h;			/* freq latch  :                   */
238 	UINT8 kcode;		/* key code    :                   */
239 } FM_CH;
240 
241 /* OPN/OPM common state */
242 typedef struct fm_state {
243 	UINT8 index;		/* chip index (number of chip) */
244 	int clock;			/* master clock  (Hz)  */
245 	int rate;			/* sampling rate (Hz)  */
246 	float freqbase;	/* frequency base      */
247 	timer_tm TimerBase;	/* Timer base time     */
248 	UINT8 address;		/* address register    */
249 	UINT8 irq;			/* interrupt level     */
250 	UINT8 irqmask;		/* irq mask            */
251 	UINT8 status;		/* status flag         */
252 	UINT32 mode;		/* mode  CSM / 3SLOT   */
253 	int TA;				/* timer a             */
254 	int TAC;			/* timer a counter     */
255 	UINT8 TB;			/* timer b             */
256 	int TBC;			/* timer b counter     */
257 	/* speedup customize */
258 	/* local time tables */
259 	INT32 DT_TABLE[8][32];	/* DeTune tables       */
260 	INT32 AR_TABLE[94];		/* Atttack rate tables */
261 	INT32 DR_TABLE[94];		/* Decay rate tables   */
262 	/* Extention Timer and IRQ handler */
263 	FM_TIMERHANDLER	Timer_Handler;
264 	FM_IRQHANDLER	IRQ_Handler;
265 	/* timer model single / interval */
266 	UINT8 timermodel;
267 }FM_ST;
268 
269 /* -------------------- tables --------------------- */
270 
271 /* sustain lebel table (3db per step) */
272 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
273 #define SC(db) (int)((db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST)
274 static const int SL_TABLE[16]={
275  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
276  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
277 };
278 #undef SC
279 
280 /* size of TL_TABLE = sinwave(max cut_off) + cut_off(tl + ksr + envelope + ams) */
281 #define TL_MAX (PG_CUT_OFF+EG_CUT_OFF+1)
282 
283 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
284 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
285 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
286 static INT32 *TL_TABLE = 0;
287 
288 /* pointers to TL_TABLE with sinwave output offset */
289 static INT32 *SIN_TABLE[SIN_ENT];
290 
291 /* envelope output curve table */
292 #if FM_SEG_SUPPORT
293 /* attack + decay + SSG upside + OFF */
294 static INT32 ENV_CURVE[3*EG_ENT+1];
295 #else
296 /* attack + decay + OFF */
297 static INT32 ENV_CURVE[2*EG_ENT+1];
298 #endif
299 /* envelope counter conversion table when change Decay to Attack phase */
300 static int DRAR_TABLE[EG_ENT];
301 
302 #define OPM_DTTABLE OPN_DTTABLE
303 static UINT8 OPN_DTTABLE[4 * 32]={
304 /* this table is YM2151 and YM2612 data */
305 /* FD=0 */
306   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 /* FD=1 */
309   0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
310   2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
311 /* FD=2 */
312   1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
313   5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
314 /* FD=3 */
315   2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
316   8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
317 };
318 
319 /* multiple table */
320 #define ML(n) (int)(n*2)
321 static const int MUL_TABLE[4*16]= {
322 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
323    ML(0.50),ML( 1.00),ML( 2.00),ML( 3.00),ML( 4.00),ML( 5.00),ML( 6.00),ML( 7.00),
324    ML(8.00),ML( 9.00),ML(10.00),ML(11.00),ML(12.00),ML(13.00),ML(14.00),ML(15.00),
325 /* DT2=1 *SQL(2)   */
326    ML(0.71),ML( 1.41),ML( 2.82),ML( 4.24),ML( 5.65),ML( 7.07),ML( 8.46),ML( 9.89),
327    ML(11.30),ML(12.72),ML(14.10),ML(15.55),ML(16.96),ML(18.37),ML(19.78),ML(21.20),
328 /* DT2=2 *SQL(2.5) */
329    ML( 0.78),ML( 1.57),ML( 3.14),ML( 4.71),ML( 6.28),ML( 7.85),ML( 9.42),ML(10.99),
330    ML(12.56),ML(14.13),ML(15.70),ML(17.27),ML(18.84),ML(20.41),ML(21.98),ML(23.55),
331 /* DT2=3 *SQL(3)   */
332    ML( 0.87),ML( 1.73),ML( 3.46),ML( 5.19),ML( 6.92),ML( 8.65),ML(10.38),ML(12.11),
333    ML(13.84),ML(15.57),ML(17.30),ML(19.03),ML(20.76),ML(22.49),ML(24.22),ML(25.95)
334 };
335 #undef ML
336 
337 #if FM_LFO_SUPPORT
338 
339 #define PMS_RATE 0x400
340 /* LFO runtime work */
341 /*static*/ UINT32 lfo_amd;
342 /*static*/ INT32 lfo_pmd;
343 #endif
344 
345 /* Dummy table of Attack / Decay rate ( use when rate == 0 ) */
346 static const INT32 RATE_0[32]=
347 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
348 
349 /* -------------------- state --------------------- */
350 
351 /* some globals */
352 #define TYPE_SSG    0x01    /* SSG support          */
353 #define TYPE_OPN    0x02    /* OPN device           */
354 #define TYPE_LFOPAN 0x04    /* OPN type LFO and PAN */
355 #define TYPE_6CH    0x08    /* FM 6CH / 3CH         */
356 #define TYPE_DAC    0x10    /* YM2612's DAC device  */
357 #define TYPE_ADPCM  0x20    /* two ADPCM unit       */
358 
359 #define TYPE_YM2203 (TYPE_SSG)
360 #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
361 #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
362 #define TYPE_YM2612 (TYPE_6CH |TYPE_LFOPAN |TYPE_DAC)
363 
364 /* current chip state */
365 static void *cur_chip = 0;		/* pointer of current chip struct */
366 static FM_ST  *State;			/* basic status */
367 static FM_CH  *cch[8];			/* pointer of FM channels */
368 #if (BUILD_LFO)
369 #if FM_LFO_SUPPORT
370 static UINT32 LFOCnt,LFOIncr;	/* LFO PhaseGenerator */
371 #endif
372 #endif
373 
374 /* runtime work */
375 /*static*/ INT32 out_ch[4];		/* channel output NONE,LEFT,RIGHT or CENTER */
376 /*static*/ INT32 pg_in1,pg_in2,pg_in3,pg_in4;	/* PG input of SLOTs */
377 
378 /* -------------------- log output  -------------------- */
379 /* log output level */
380 #define LOG_ERR  3      /* ERROR       */
381 #define LOG_WAR  2      /* WARNING     */
382 #define LOG_INF  1      /* INFORMATION */
383 #define LOG_LEVEL LOG_INF
384 
385 //#ifndef __RAINE__
386 //#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
387 //#endif
388 #define LOG(n,x)
389 
390 /* ----- limitter ----- */
391 #define Limit(val, max,min) { \
392 	if ( val > max )      val = max; \
393 	else if ( val < min ) val = min; \
394 }
395 
396 #ifndef mix_sample
397 	/* ----- buffering one of data(STEREO chip) ----- */
398 	#if FM_STEREO_MIX
399 	/* stereo mixing */
400 	#define FM_BUFFERING_STEREO \
401 	{														\
402 		/* get left & right output with clipping */			\
403 		out_ch[OUTD_LEFT]  += out_ch[OUTD_CENTER];				\
404 		Limit( out_ch[OUTD_LEFT] , FM_MAXOUT, FM_MINOUT );	\
405 		out_ch[OUTD_RIGHT] += out_ch[OUTD_CENTER];				\
406 		Limit( out_ch[OUTD_RIGHT], FM_MAXOUT, FM_MINOUT );	\
407 		/* buffering */										\
408 		*bufL++ = out_ch[OUTD_LEFT] >>FM_OUTSB;				\
409 		*bufL++ = out_ch[OUTD_RIGHT]>>FM_OUTSB;				\
410 	}
411 	#else
412 	/* stereo separate */
413 	#define FM_BUFFERING_STEREO \
414 	{														\
415 		/* get left & right output with clipping */			\
416 		out_ch[OUTD_LEFT]  += out_ch[OUTD_CENTER];				\
417 		Limit( out_ch[OUTD_LEFT] , FM_MAXOUT, FM_MINOUT );	\
418 		out_ch[OUTD_RIGHT] += out_ch[OUTD_CENTER];				\
419 		Limit( out_ch[OUTD_RIGHT], FM_MAXOUT, FM_MINOUT );	\
420 		/* buffering */										\
421 		*bufL++ = out_ch[OUTD_LEFT] >>FM_OUTSB;				\
422 		*bufR++ = out_ch[OUTD_RIGHT]>>FM_OUTSB;				\
423 	}
424 	#endif
425 #else
426 	#if FM_STEREO_MIX
427 	#define FM_BUFFERING_STEREO \
428 	{ \
429 		mix_sample(out_ch[OUTD_LEFT],out_ch[OUTD_CENTER]); \
430 		*bufL++=out_ch[OUTD_LEFT] >>FM_OUTSB; \
431 		mix_sample(out_ch[OUTD_RIGHT],out_ch[OUTD_CENTER]); \
432 		*bufR++=out_ch[OUTD_RIGHT] >>FM_OUTSB; \
433 	}
434 	#else
435 	#define FM_BUFFERING_STEREO \
436 	{ \
437 		mix_sample(out_ch[OUTD_LEFT],out_ch[OUTD_CENTER]); \
438 		*bufL++=out_ch[OUTD_LEFT] >>FM_OUTSB; \
439 		mix_sample(out_ch[OUTD_RIGHT],out_ch[OUTD_CENTER]); \
440 		*bufR++=out_ch[OUTD_RIGHT] >>FM_OUTSB; \
441 	}
442 	#endif
443 #endif
444 
445 #if FM_INTERNAL_TIMER
446 /* ----- internal timer mode , update timer */
447 /* ---------- calcrate timer A ---------- */
448 #define INTERNAL_TIMER_A(ST,CSM_CH)					\
449 {													\
450 	if( ST->TAC &&  (ST->Timer_Handler==0) )		\
451 		if( (ST->TAC -= (int)(ST->freqbase*4096)) <= 0 )	\
452 		{											\
453 			TimerAOver( ST );						\
454 			/* CSM mode total level latch and auto key on */	\
455 			if( ST->mode & 0x80 )					\
456 				CSMKeyControll( CSM_CH );			\
457 		}											\
458 }
459 /* ---------- calcrate timer B ---------- */
460 #define INTERNAL_TIMER_B(ST,step)						\
461 {														\
462 	if( ST->TBC && (ST->Timer_Handler==0) )				\
463 		if( (ST->TBC -= (int)(ST->freqbase*4096*step)) <= 0 )	\
464 			TimerBOver( ST );							\
465 }
466 #else /* FM_INTERNAL_TIMER */
467 /* external timer mode */
468 #define INTERNAL_TIMER_A(ST,CSM_CH)
469 #define INTERNAL_TIMER_B(ST,step)
470 #endif /* FM_INTERNAL_TIMER */
471 
472 /* --------------------- subroutines  --------------------- */
473 /* status set and IRQ handling */
FM_STATUS_SET(FM_ST * ST,int flag)474 static INLINE void FM_STATUS_SET(FM_ST *ST,int flag)
475 {
476 	/* set status flag */
477 	ST->status |= flag;
478 	if ( !(ST->irq) && (ST->status & ST->irqmask) )
479 	{
480 		ST->irq = 1;
481 		/* callback user interrupt handler (IRQ is OFF to ON) */
482 		if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,1);
483 	}
484 }
485 
486 /* status reset and IRQ handling */
FM_STATUS_RESET(FM_ST * ST,int flag)487 static INLINE void FM_STATUS_RESET(FM_ST *ST,int flag)
488 {
489 	/* reset status flag */
490 	ST->status &=~flag;
491 	if ( (ST->irq) && !(ST->status & ST->irqmask) )
492 	{
493 		ST->irq = 0;
494 		/* callback user interrupt handler (IRQ is ON to OFF) */
495 		if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,0);
496 	}
497 }
498 
499 /* IRQ mask set */
FM_IRQMASK_SET(FM_ST * ST,int flag)500 static INLINE void FM_IRQMASK_SET(FM_ST *ST,int flag)
501 {
502 	ST->irqmask = flag;
503 	/* IRQ handling check */
504 	FM_STATUS_SET(ST,0);
505 	FM_STATUS_RESET(ST,0);
506 }
507 
508 /* ---------- event hander of Phase Generator ---------- */
509 
510 /* Release end -> stop counter */
FM_EG_Release(FM_SLOT * SLOT)511 static void FM_EG_Release( FM_SLOT *SLOT )
512 {
513 	SLOT->evc = EG_OFF;
514 	SLOT->eve = EG_OFF+1;
515 	SLOT->evs = 0;
516 }
517 
518 /* SUSTAIN end -> stop counter */
FM_EG_SR(FM_SLOT * SLOT)519 static void FM_EG_SR( FM_SLOT *SLOT )
520 {
521 	SLOT->evs = 0;
522 	SLOT->evc = EG_OFF;
523 	SLOT->eve = EG_OFF+1;
524 }
525 
526 /* Decay end -> Sustain */
FM_EG_DR(FM_SLOT * SLOT)527 static void FM_EG_DR( FM_SLOT *SLOT )
528 {
529 	SLOT->eg_next = FM_EG_SR;
530 	SLOT->evc = SLOT->SL;
531 	SLOT->eve = EG_DED;
532 	SLOT->evs = SLOT->evss;
533 }
534 
535 /* Attack end -> Decay */
FM_EG_AR(FM_SLOT * SLOT)536 static void FM_EG_AR( FM_SLOT *SLOT )
537 {
538 	/* next DR */
539 	SLOT->eg_next = FM_EG_DR;
540 	SLOT->evc = EG_DST;
541 	SLOT->eve = SLOT->SL;
542 	SLOT->evs = SLOT->evsd;
543 }
544 
545 #if FM_SEG_SUPPORT
546 static void FM_EG_SSG_SR( FM_SLOT *SLOT );
547 
548 /* SEG down side end  */
FM_EG_SSG_DR(FM_SLOT * SLOT)549 static void FM_EG_SSG_DR( FM_SLOT *SLOT )
550 {
551 	if( SLOT->SEG&2){
552 		/* reverce */
553 		SLOT->eg_next = FM_EG_SSG_SR;
554 		SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
555 		SLOT->eve = EG_UED;
556 		SLOT->evs = SLOT->evss;
557 	}else{
558 		/* again */
559 		SLOT->evc = EG_DST;
560 	}
561 	/* hold */
562 	if( SLOT->SEG&1) SLOT->evs = 0;
563 }
564 
565 /* SEG upside side end */
FM_EG_SSG_SR(FM_SLOT * SLOT)566 static void FM_EG_SSG_SR( FM_SLOT *SLOT )
567 {
568 	if( SLOT->SEG&2){
569 		/* reverce  */
570 		SLOT->eg_next = FM_EG_SSG_DR;
571 		SLOT->evc = EG_DST;
572 		SLOT->eve = EG_DED;
573 		SLOT->evs = SLOT->evsd;
574 	}else{
575 		/* again */
576 		SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
577 	}
578 	/* hold check */
579 	if( SLOT->SEG&1) SLOT->evs = 0;
580 }
581 
582 /* SEG Attack end */
FM_EG_SSG_AR(FM_SLOT * SLOT)583 static void FM_EG_SSG_AR( FM_SLOT *SLOT )
584 {
585 	if( SLOT->SEG&4){	/* start direction */
586 		/* next SSG-SR (upside start ) */
587 		SLOT->eg_next = FM_EG_SSG_SR;
588 		SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
589 		SLOT->eve = EG_UED;
590 		SLOT->evs = SLOT->evss;
591 	}else{
592 		/* next SSG-DR (downside start ) */
593 		SLOT->eg_next = FM_EG_SSG_DR;
594 		SLOT->evc = EG_DST;
595 		SLOT->eve = EG_DED;
596 		SLOT->evs = SLOT->evsd;
597 	}
598 }
599 #endif /* FM_SEG_SUPPORT */
600 
601 /* ----- key on of SLOT ----- */
602 #define FM_KEY_IS(SLOT) ((SLOT)->eg_next!=FM_EG_Release)
603 
FM_KEYON(FM_CH * CH,int s)604 static INLINE void FM_KEYON(FM_CH *CH , int s )
605 {
606 	FM_SLOT *SLOT = &CH->SLOT[s];
607 	if( !FM_KEY_IS(SLOT) )
608 	{
609 		/* restart Phage Generator */
610 		SLOT->Cnt = 0;
611 		/* phase -> Attack */
612 #if FM_SEG_SUPPORT
613 		if( SLOT->SEG&8 ) SLOT->eg_next = FM_EG_SSG_AR;
614 		else
615 #endif
616 		SLOT->eg_next = FM_EG_AR;
617 		SLOT->evs     = SLOT->evsa;
618 #if 0
619 		/* convert decay count to attack count */
620 		/* --- This caused the problem by credit sound of paper boy. --- */
621 		SLOT->evc = EG_AST + DRAR_TABLE[ENV_CURVE[SLOT->evc>>ENV_BITS]];/* + SLOT->evs;*/
622 #else
623 		/* reset attack counter */
624 		SLOT->evc = EG_AST;
625 #endif
626 		SLOT->eve = EG_AED;
627 	}
628 }
629 /* ----- key off of SLOT ----- */
FM_KEYOFF(FM_CH * CH,int s)630 static INLINE void FM_KEYOFF(FM_CH *CH , int s )
631 {
632 	FM_SLOT *SLOT = &CH->SLOT[s];
633 	if( FM_KEY_IS(SLOT) )
634 	{
635 		/* if Attack phase then adjust envelope counter */
636 		if( SLOT->evc < EG_DST )
637 			SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
638 		/* phase -> Release */
639 		SLOT->eg_next = FM_EG_Release;
640 		SLOT->eve     = EG_DED;
641 		SLOT->evs     = SLOT->evsr;
642 	}
643 }
644 
645 /* setup Algorythm and PAN connection */
setup_connection(FM_CH * CH)646 static void setup_connection( FM_CH *CH )
647 {
648 	INT32 *carrier = &out_ch[CH->PAN]; /* NONE,LEFT,RIGHT or CENTER */
649 
650 	switch( CH->ALGO ){
651 	case 0:
652 		/*  PG---S1---S2---S3---S4---OUT */
653 		CH->connect1 = &pg_in2;
654 		CH->connect2 = &pg_in3;
655 		CH->connect3 = &pg_in4;
656 		break;
657 	case 1:
658 		/*  PG---S1-+-S3---S4---OUT */
659 		/*  PG---S2-+               */
660 		CH->connect1 = &pg_in3;
661 		CH->connect2 = &pg_in3;
662 		CH->connect3 = &pg_in4;
663 		break;
664 	case 2:
665 		/* PG---S1------+-S4---OUT */
666 		/* PG---S2---S3-+          */
667 		CH->connect1 = &pg_in4;
668 		CH->connect2 = &pg_in3;
669 		CH->connect3 = &pg_in4;
670 		break;
671 	case 3:
672 		/* PG---S1---S2-+-S4---OUT */
673 		/* PG---S3------+          */
674 		CH->connect1 = &pg_in2;
675 		CH->connect2 = &pg_in4;
676 		CH->connect3 = &pg_in4;
677 		break;
678 	case 4:
679 		/* PG---S1---S2-+--OUT */
680 		/* PG---S3---S4-+      */
681 		CH->connect1 = &pg_in2;
682 		CH->connect2 = carrier;
683 		CH->connect3 = &pg_in4;
684 		break;
685 	case 5:
686 		/*         +-S2-+     */
687 		/* PG---S1-+-S3-+-OUT */
688 		/*         +-S4-+     */
689 		CH->connect1 = 0;	/* special case */
690 		CH->connect2 = carrier;
691 		CH->connect3 = carrier;
692 		break;
693 	case 6:
694 		/* PG---S1---S2-+     */
695 		/* PG--------S3-+-OUT */
696 		/* PG--------S4-+     */
697 		CH->connect1 = &pg_in2;
698 		CH->connect2 = carrier;
699 		CH->connect3 = carrier;
700 		break;
701 	case 7:
702 		/* PG---S1-+     */
703 		/* PG---S2-+-OUT */
704 		/* PG---S3-+     */
705 		/* PG---S4-+     */
706 		CH->connect1 = carrier;
707 		CH->connect2 = carrier;
708 		CH->connect3 = carrier;
709 	}
710 	CH->connect4 = carrier;
711 }
712 
713 /* set detune & multiple */
set_det_mul(FM_ST * ST,FM_CH * CH,FM_SLOT * SLOT,int v)714 static INLINE void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
715 {
716 	SLOT->mul = MUL_TABLE[v&0x0f];
717 	SLOT->DT  = ST->DT_TABLE[(v>>4)&7];
718 	CH->SLOT[SLOT1].Incr=-1;
719 }
720 
721 /* set total level */
set_tl(FM_CH * CH,FM_SLOT * SLOT,int v,int csmflag)722 static INLINE void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v,int csmflag)
723 {
724 	v &= 0x7f;
725 	v = (v<<7)|v; /* 7bit -> 14bit */
726 	SLOT->TL = (v*EG_ENT)>>14;
727 	/* if it is not a CSM channel , latch the total level */
728 	if( !csmflag )
729 		SLOT->TLL = SLOT->TL;
730 }
731 
732 /* set attack rate & key scale  */
set_ar_ksr(FM_CH * CH,FM_SLOT * SLOT,int v,INT32 * ar_table)733 static INLINE void set_ar_ksr(FM_CH *CH,FM_SLOT *SLOT,int v,INT32 *ar_table)
734 {
735 	SLOT->KSR  = 3-(v>>6);
736 	SLOT->AR   = (v&=0x1f) ? &ar_table[v<<1] : RATE_0;
737 	SLOT->evsa = SLOT->AR[SLOT->ksr];
738 	if( SLOT->eg_next == FM_EG_AR ) SLOT->evs = SLOT->evsa;
739 	CH->SLOT[SLOT1].Incr=-1;
740 }
741 /* set decay rate */
set_dr(FM_SLOT * SLOT,int v,INT32 * dr_table)742 static INLINE void set_dr(FM_SLOT *SLOT,int v,INT32 *dr_table)
743 {
744 	SLOT->DR = (v&=0x1f) ? &dr_table[v<<1] : RATE_0;
745 	SLOT->evsd = SLOT->DR[SLOT->ksr];
746 	if( SLOT->eg_next == FM_EG_DR ) SLOT->evs = SLOT->evsd;
747 }
748 /* set sustain rate */
set_sr(FM_SLOT * SLOT,int v,INT32 * dr_table)749 static INLINE void set_sr(FM_SLOT *SLOT,int v,INT32 *dr_table)
750 {
751 	SLOT->SR = (v&=0x1f) ? &dr_table[v<<1] : RATE_0;
752 	SLOT->evss = SLOT->SR[SLOT->ksr];
753 	if( SLOT->eg_next == FM_EG_SR ) SLOT->evs = SLOT->evss;
754 }
755 /* set release rate */
set_sl_rr(FM_SLOT * SLOT,int v,INT32 * dr_table)756 static INLINE void set_sl_rr(FM_SLOT *SLOT,int v,INT32 *dr_table)
757 {
758 	SLOT->SL = SL_TABLE[(v>>4)];
759 	SLOT->RR = &dr_table[((v&0x0f)<<2)|2];
760 	SLOT->evsr = SLOT->RR[SLOT->ksr];
761 	if( SLOT->eg_next == FM_EG_Release ) SLOT->evs = SLOT->evsr;
762 }
763 
764 /* operator output calcrator */
765 //#define OP_OUT(PG,EG)   SIN_TABLE[(PG/(0x1000000/SIN_ENT))&(SIN_ENT-1)][EG]
766 //#define OP_OUTN(PG,EG)  NOISE_TABLE[(PG/(0x1000000/SIN_ENT))&(SIN_ENT-1)][EG]
767 #define OP_OUT(PG,EG)   SIN_TABLE[(PG>>13)&0x7ff][EG]
768 #define OP_OUTN(PG,EG)  NOISE_TABLE[(PG>>13)&0x7ff][EG]
769 
770 /* eg calcration */
771 #if FM_LFO_SUPPORT
772 #define FM_CALC_EG(OUT,SLOT)						\
773 {													\
774 	if( (SLOT.evc += SLOT.evs) >= SLOT.eve) 		\
775 		SLOT.eg_next(&(SLOT));						\
776 	OUT = SLOT.TLL+ENV_CURVE[SLOT.evc>>ENV_BITS];	\
777 	if(SLOT.ams)									\
778 		OUT += (SLOT.ams*lfo_amd/LFO_RATE);			\
779 }
780 #else
781 #define FM_CALC_EG(OUT,SLOT)						\
782 {													\
783 	if( (SLOT.evc += SLOT.evs) >= SLOT.eve) 		\
784 		SLOT.eg_next(&(SLOT));						\
785 	OUT = SLOT.TLL+ENV_CURVE[SLOT.evc>>ENV_BITS];	\
786 }
787 #endif
788 
789 /* ---------- calcrate one of channel ---------- */
FM_CALC_CH(FM_CH * CH)790 static INLINE void FM_CALC_CH( FM_CH *CH )
791 {
792 	UINT32 eg_out1,eg_out2,eg_out3,eg_out4;  //envelope output
793 
794 	/* Phase Generator */
795 #if FM_LFO_SUPPORT
796 	INT32 pms = lfo_pmd * CH->pms / LFO_RATE;
797 	if(pms)
798 	{
799 		pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr + (INT32)(pms * CH->SLOT[SLOT1].Incr) / PMS_RATE);
800 		pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr + (INT32)(pms * CH->SLOT[SLOT2].Incr) / PMS_RATE);
801 		pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr + (INT32)(pms * CH->SLOT[SLOT3].Incr) / PMS_RATE);
802 		pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr + (INT32)(pms * CH->SLOT[SLOT4].Incr) / PMS_RATE);
803 	}
804 	else
805 #endif
806 	{
807 		pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr);
808 		pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr);
809 		pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr);
810 		pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr);
811 	}
812 
813 	/* Envelope Generator */
814 	FM_CALC_EG(eg_out1,CH->SLOT[SLOT1]);
815 	FM_CALC_EG(eg_out2,CH->SLOT[SLOT2]);
816 	FM_CALC_EG(eg_out3,CH->SLOT[SLOT3]);
817 	FM_CALC_EG(eg_out4,CH->SLOT[SLOT4]);
818 
819 	/* Connection */
820 	if( eg_out1 < EG_CUT_OFF )	/* SLOT 1 */
821 	{
822 		if( CH->FB ){
823 			/* with self feed back */
824 			pg_in1 += (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
825 			CH->op1_out[1] = CH->op1_out[0];
826 		}
827 		CH->op1_out[0] = OP_OUT(pg_in1,eg_out1);
828 		/* output slot1 */
829 		if( !CH->connect1 )
830 		{
831 			/* algorythm 5  */
832 			pg_in2 += CH->op1_out[0];
833 			pg_in3 += CH->op1_out[0];
834 			pg_in4 += CH->op1_out[0];
835 		}else{
836 			/* other algorythm */
837 			*CH->connect1 += CH->op1_out[0];
838 		}
839 	}
840 	if( eg_out2 < EG_CUT_OFF )	/* SLOT 2 */
841 		*CH->connect2 += OP_OUT(pg_in2,eg_out2);
842 	if( eg_out3 < EG_CUT_OFF )	/* SLOT 3 */
843 		*CH->connect3 += OP_OUT(pg_in3,eg_out3);
844 	if( eg_out4 < EG_CUT_OFF )	/* SLOT 4 */
845 		*CH->connect4 += OP_OUT(pg_in4,eg_out4);
846 }
847 /* ---------- frequency counter for operater update ---------- */
CALC_FCSLOT(FM_SLOT * SLOT,int fc,int kc)848 static INLINE void CALC_FCSLOT(FM_SLOT *SLOT , int fc , int kc )
849 {
850 	int ksr;
851 
852 	/* frequency step counter */
853 	/* SLOT->Incr= (fc+SLOT->DT[kc])*SLOT->mul; */
854 	SLOT->Incr= fc*SLOT->mul + SLOT->DT[kc];
855 	ksr = kc >> SLOT->KSR;
856 	if( SLOT->ksr != ksr )
857 	{
858 		SLOT->ksr = ksr;
859 		/* attack , decay rate recalcration */
860 		SLOT->evsa = SLOT->AR[ksr];
861 		SLOT->evsd = SLOT->DR[ksr];
862 		SLOT->evss = SLOT->SR[ksr];
863 		SLOT->evsr = SLOT->RR[ksr];
864 	}
865 }
866 
867 /* ---------- frequency counter  ---------- */
OPN_CALC_FCOUNT(FM_CH * CH)868 static INLINE void OPN_CALC_FCOUNT(FM_CH *CH )
869 {
870 	if( CH->SLOT[SLOT1].Incr==-1){
871 		int fc = CH->fc;
872 		int kc = CH->kcode;
873 		CALC_FCSLOT(&CH->SLOT[SLOT1] , fc , kc );
874 		CALC_FCSLOT(&CH->SLOT[SLOT2] , fc , kc );
875 		CALC_FCSLOT(&CH->SLOT[SLOT3] , fc , kc );
876 		CALC_FCSLOT(&CH->SLOT[SLOT4] , fc , kc );
877 	}
878 }
879 
880 /* ----------- initialize time tabls ----------- */
init_timetables(FM_ST * ST,UINT8 * DTTABLE,int ARRATE,int DRRATE)881 static void init_timetables( FM_ST *ST , UINT8 *DTTABLE , int ARRATE , int DRRATE )
882 {
883 	int i,d;
884 	float rate;
885 
886 	/* DeTune table */
887 	for (d = 0;d <= 3;d++){
888 		for (i = 0;i <= 31;i++){
889 			rate = (float)DTTABLE[d*32 + i] * ST->freqbase * FREQ_RATE;
890 			ST->DT_TABLE[d][i]   = (INT32) rate;
891 			ST->DT_TABLE[d+4][i] = (INT32)-rate;
892 		}
893 	}
894 	/* make Attack & Decay tables */
895 	for (i = 0;i < 4;i++) ST->AR_TABLE[i] = ST->DR_TABLE[i] = 0;
896 	for (i = 4;i < 64;i++){
897 		rate  = ST->freqbase;						/* frequency rate */
898 		if( i < 60 ) rate *= 1.0+(i&3)*0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
899 		rate *= 1<<((i>>2)-1);						/* b2-5 : shift bit */
900 		rate *= (float)(EG_ENT<<ENV_BITS);
901 		ST->AR_TABLE[i] = (INT32)(rate / ARRATE);
902 		ST->DR_TABLE[i] = (INT32)(rate / DRRATE);
903 	}
904 	ST->AR_TABLE[62] = EG_AED;
905 	ST->AR_TABLE[63] = EG_AED;
906 	for (i = 64;i < 94 ;i++){	/* make for overflow area */
907 		ST->AR_TABLE[i] = ST->AR_TABLE[63];
908 		ST->DR_TABLE[i] = ST->DR_TABLE[63];
909 	}
910 
911 #if 0
912 	for (i = 0;i < 64 ;i++){
913 		LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
914 			((float)(EG_ENT<<ENV_BITS) / ST->AR_TABLE[i]) * (1000.0 / ST->rate),
915 			((float)(EG_ENT<<ENV_BITS) / ST->DR_TABLE[i]) * (1000.0 / ST->rate) ));
916 	}
917 #endif
918 }
919 
920 /* ---------- reset one of channel  ---------- */
reset_channel(FM_ST * ST,FM_CH * CH,int chan)921 static void reset_channel( FM_ST *ST , FM_CH *CH , int chan )
922 {
923 	int c,s;
924 
925 	ST->mode   = 0;	/* normal mode */
926 	FM_STATUS_RESET(ST,0xff);
927 	ST->TA     = 0;
928 	ST->TAC    = 0;
929 	ST->TB     = 0;
930 	ST->TBC    = 0;
931 
932 	for( c = 0 ; c < chan ; c++ )
933 	{
934 		CH[c].fc = 0;
935 		CH[c].PAN = OUTD_CENTER;
936 		for(s = 0 ; s < 4 ; s++ )
937 		{
938 			CH[c].SLOT[s].SEG = 0;
939 			CH[c].SLOT[s].eg_next= FM_EG_Release;
940 			CH[c].SLOT[s].evc = EG_OFF;
941 			CH[c].SLOT[s].eve = EG_OFF+1;
942 			CH[c].SLOT[s].evs = 0;
943 		}
944 	}
945 }
946 
947 /* ---------- generic table initialize ---------- */
FMInitTable(void)948 static int FMInitTable( void )
949 {
950 	int s,t;
951 	double rate;
952 	int i,j;
953 	double pom;
954 
955 	if (TL_TABLE)
956 	{
957 		return 1;	/* Already initialized */
958 	}
959 
960 	/* allocate total level table plus+minus section */
961 	TL_TABLE = (INT32 *)malloc(2*TL_MAX*sizeof(int));
962 	if( TL_TABLE == 0 ) return 0;
963 	/* make total level table */
964 	for (t = 0;t < TL_MAX ;t++){
965 		if(t >= PG_CUT_OFF)
966 			rate = 0;	/* under cut off area */
967 		else
968 			rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);	/* dB -> voltage */
969 		TL_TABLE[       t] =  (int)rate;
970 		TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
971 /*		LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
972 	}
973 
974 	/* make sinwave table (pointer of total level) */
975 	for (s = 1;s <= SIN_ENT/4;s++){
976 		pom = sin(2.0*PI*s/SIN_ENT); /* sin   */
977 		pom = 20*log10(1/pom);	     /* -> decibel */
978 		j = (int)(pom / EG_STEP);    /* TL_TABLE steps */
979 		/* cut off check */
980 		if(j > PG_CUT_OFF)
981 			j = PG_CUT_OFF;
982 		/* degree 0   -  90    , degree 180 -  90 : plus section */
983 		SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
984 		/* degree 180 - 270    , degree 360 - 270 : minus section */
985 		SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
986 		/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP)); */
987 	}
988 	/* degree 0 = degree 180                   = off */
989 	SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2]        = &TL_TABLE[PG_CUT_OFF];
990 
991 	/* envelope counter -> envelope output table */
992 	for (i=0; i<EG_ENT; i++)
993 	{
994 		/* ATTACK curve */
995 		/* !!!!! preliminary !!!!! */
996 		pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
997 		/* if( pom >= EG_ENT ) pom = EG_ENT-1; */
998 		ENV_CURVE[i] = (int)pom;
999 		/* DECAY ,RELEASE curve */
1000 		ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
1001 #if FM_SEG_SUPPORT
1002 		/* DECAY UPSIDE (SSG ENV) */
1003 		ENV_CURVE[(EG_UST>>ENV_BITS)+i]= EG_ENT-1-i;
1004 #endif
1005 	}
1006 	/* off */
1007 	ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
1008 
1009 	/* decay to reattack envelope converttable */
1010 	j = EG_ENT-1;
1011 	for (i=0; i<EG_ENT; i++)
1012 	{
1013 		while( j && (ENV_CURVE[j] < i) ) j--;
1014 		DRAR_TABLE[i] = j<<ENV_BITS;
1015 		/* LOG(LOG_INF,("DR %06X = %06X,AR=%06X\n",i,DRAR_TABLE[i],ENV_CURVE[DRAR_TABLE[i]>>ENV_BITS] )); */
1016 	}
1017 	return 1;
1018 }
1019 
1020 
FMCloseTable(void)1021 static void FMCloseTable( void )
1022 {
1023 	if( TL_TABLE ) free( TL_TABLE );
1024 	TL_TABLE = 0;
1025 	return;
1026 }
1027 
1028 /* OPN/OPM Mode  Register Write */
FMSetMode(FM_ST * ST,int n,int v)1029 static INLINE void FMSetMode( FM_ST *ST ,int n,int v )
1030 {
1031 	/* b7 = CSM MODE */
1032 	/* b6 = 3 slot mode */
1033 	/* b5 = reset b */
1034 	/* b4 = reset a */
1035 	/* b3 = timer enable b */
1036 	/* b2 = timer enable a */
1037 	/* b1 = load b */
1038 	/* b0 = load a */
1039 	ST->mode = v;
1040 
1041 	/* reset Timer b flag */
1042 	if( v & 0x20 )
1043 		FM_STATUS_RESET(ST,0x02);
1044 	/* reset Timer a flag */
1045 	if( v & 0x10 )
1046 		FM_STATUS_RESET(ST,0x01);
1047 	/* load b */
1048 	if( v & 0x02 )
1049 	{
1050 		if( ST->TBC == 0 )
1051 		{
1052 			ST->TBC = ( 256-ST->TB)<<4;
1053 			/* External timer handler */
1054 			if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,ST->TBC,ST->TimerBase);
1055 		}
1056 	}else if (ST->timermodel == FM_TIMER_INTERVAL)
1057 	{	/* stop interbval timer */
1058 		if( ST->TBC != 0 )
1059 		{
1060 			ST->TBC = 0;
1061 			if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,0,ST->TimerBase);
1062 		}
1063 	}
1064 	/* load a */
1065 	if( v & 0x01 )
1066 	{
1067 		if( ST->TAC == 0 )
1068 		{
1069 			ST->TAC = (1024-ST->TA);
1070 			/* External timer handler */
1071 			if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,ST->TAC,ST->TimerBase);
1072 		}
1073 	}else if (ST->timermodel == FM_TIMER_INTERVAL)
1074 	{	/* stop interbval timer */
1075 		if( ST->TAC != 0 )
1076 		{
1077 			ST->TAC = 0;
1078 			if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,0,ST->TimerBase);
1079 		}
1080 	}
1081 }
1082 
1083 /* Timer A Overflow */
TimerAOver(FM_ST * ST)1084 static INLINE void TimerAOver(FM_ST *ST)
1085 {
1086 	/* status set if enabled */
1087 	if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
1088 	/* clear or reload the counter */
1089 	if (ST->timermodel == FM_TIMER_INTERVAL)
1090 	{
1091 		ST->TAC = (1024-ST->TA);
1092 		if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,0,ST->TAC,ST->TimerBase);
1093 	}
1094 	else ST->TAC = 0;
1095 }
1096 /* Timer B Overflow */
TimerBOver(FM_ST * ST)1097 static INLINE void TimerBOver(FM_ST *ST)
1098 {
1099 	/* status set if enabled */
1100 	if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
1101 	/* clear or reload the counter */
1102 	if (ST->timermodel == FM_TIMER_INTERVAL)
1103 	{
1104 		ST->TBC = ( 256-ST->TB)<<4;
1105 		if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,1,ST->TBC,ST->TimerBase);
1106 	}
1107 	else ST->TBC = 0;
1108 }
1109 /* CSM Key Controll */
CSMKeyControll(FM_CH * CH)1110 static INLINE void CSMKeyControll(FM_CH *CH)
1111 {
1112 	/* all key off */
1113 	/* FM_KEYOFF(CH,SLOT1); */
1114 	/* FM_KEYOFF(CH,SLOT2); */
1115 	/* FM_KEYOFF(CH,SLOT3); */
1116 	/* FM_KEYOFF(CH,SLOT4); */
1117 	/* total level latch */
1118 	CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL;
1119 	CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL;
1120 	CH->SLOT[SLOT3].TLL = CH->SLOT[SLOT3].TL;
1121 	CH->SLOT[SLOT4].TLL = CH->SLOT[SLOT4].TL;
1122 	/* all key on */
1123 	FM_KEYON(CH,SLOT1);
1124 	FM_KEYON(CH,SLOT2);
1125 	FM_KEYON(CH,SLOT3);
1126 	FM_KEYON(CH,SLOT4);
1127 }
1128 
1129 #if BUILD_OPN
1130 /***********************************************************/
1131 /* OPN unit                                                */
1132 /***********************************************************/
1133 
1134 /* OPN 3slot struct */
1135 typedef struct opn_3slot {
1136 	UINT32  fc[3];		/* fnum3,blk3  :calcrated */
1137 	UINT8 fn_h[3];		/* freq3 latch            */
1138 	UINT8 kcode[3];		/* key code    :          */
1139 }FM_3SLOT;
1140 
1141 /* OPN/A/B common state */
1142 typedef struct opn_f {
1143 	UINT8 type;		/* chip type         */
1144 	FM_ST ST;				/* general state     */
1145 	FM_3SLOT SL3;			/* 3 slot mode state */
1146 	FM_CH *P_CH;			/* pointer of CH     */
1147 	UINT32 FN_TABLE[2048]; /* fnumber -> increment counter */
1148 #if FM_LFO_SUPPORT
1149 	/* LFO */
1150 	UINT32 LFOCnt;
1151 	UINT32 LFOIncr;
1152 	UINT32 LFO_FREQ[8];/* LFO FREQ table */
1153 #endif
1154 } FM_OPN;
1155 
1156 /* OPN key frequency number -> key code follow table */
1157 /* fnum higher 4bit -> keycode lower 2bit */
1158 static const UINT8 OPN_FKTABLE[16]={0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
1159 
1160 #if FM_LFO_SUPPORT
1161 /* OPN LFO waveform table */
1162 static INT32 OPN_LFO_wave[LFO_ENT];
1163 #endif
1164 
OPNInitTable(void)1165 static int OPNInitTable(void)
1166 {
1167 	int i;
1168 
1169 #if FM_LFO_SUPPORT
1170 	/* LFO wave table */
1171 	for(i=0;i<LFO_ENT;i++)
1172 	{
1173 		OPN_LFO_wave[i]= i<LFO_ENT/2 ? i*LFO_RATE/(LFO_ENT/2) : (LFO_ENT-i)*LFO_RATE/(LFO_ENT/2);
1174 	}
1175 #endif
1176 	return FMInitTable();
1177 }
1178 
1179 /* ---------- priscaler set(and make time tables) ---------- */
OPNSetPris(FM_OPN * OPN,int pris,int TimerPris,int SSGpris)1180 static void OPNSetPris(FM_OPN *OPN , int pris , int TimerPris, int SSGpris)
1181 {
1182 	int i;
1183 
1184 	/* frequency base */
1185 	OPN->ST.freqbase = (OPN->ST.rate) ? ((float)OPN->ST.clock / OPN->ST.rate) / pris : 0;
1186 	/* Timer base time */
1187 	OPN->ST.TimerBase = (float)TIME_ONE_SEC/((float)OPN->ST.clock / (float)TimerPris);
1188 	/* SSG part  priscaler set */
1189 	if( SSGpris ) SSGClk( OPN->ST.index, OPN->ST.clock * 2 / SSGpris );
1190 	/* make time tables */
1191 	init_timetables( &OPN->ST , OPN_DTTABLE , OPN_ARRATE , OPN_DRRATE );
1192 	/* make fnumber -> increment counter table */
1193 	for( i=0 ; i < 2048 ; i++ )
1194 	{
1195 		/* it is freq table for octave 7 */
1196 		/* opn freq counter = 20bit */
1197 		OPN->FN_TABLE[i] = (UINT32)( (float)i * OPN->ST.freqbase * FREQ_RATE * (1<<7) / 2 );
1198 	}
1199 #if FM_LFO_SUPPORT
1200 	/* LFO freq. table */
1201 	{
1202 		/* 3.98Hz,5.56Hz,6.02Hz,6.37Hz,6.88Hz,9.63Hz,48.1Hz,72.2Hz @ 8MHz */
1203 #define FM_LF(Hz) ((float)LFO_ENT*(1<<LFO_SHIFT)*(Hz)/(8000000.0/144))
1204 		static const float freq_table[8] = { FM_LF(3.98),FM_LF(5.56),FM_LF(6.02),FM_LF(6.37),FM_LF(6.88),FM_LF(9.63),FM_LF(48.1),FM_LF(72.2) };
1205 #undef FM_LF
1206 		for(i=0;i<8;i++)
1207 		{
1208 			OPN->LFO_FREQ[i] = (UINT32)(freq_table[i] * OPN->ST.freqbase);
1209 		}
1210 	}
1211 #endif
1212 /*	LOG(LOG_INF,("OPN %d set priscaler %d\n",OPN->ST.index,pris));*/
1213 }
1214 
1215 /* ---------- write a OPN mode register 0x20-0x2f ---------- */
OPNWriteMode(FM_OPN * OPN,int r,int v)1216 static void OPNWriteMode(FM_OPN *OPN, int r, int v)
1217 {
1218 	UINT8 c;
1219 	FM_CH *CH;
1220 
1221 	switch(r){
1222 	case 0x21:	/* Test */
1223 		break;
1224 #if FM_LFO_SUPPORT
1225 	case 0x22:	/* LFO FREQ (YM2608/YM2612) */
1226 		if( OPN->type & TYPE_LFOPAN )
1227 		{
1228 			OPN->LFOIncr = (v&0x08) ? OPN->LFO_FREQ[v&7] : 0;
1229 			cur_chip = NULL;
1230 		}
1231 		break;
1232 #endif
1233 	case 0x24:	/* timer A High 8*/
1234 		OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
1235 		break;
1236 	case 0x25:	/* timer A Low 2*/
1237 		OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
1238 		break;
1239 	case 0x26:	/* timer B */
1240 		OPN->ST.TB = v;
1241 		break;
1242 	case 0x27:	/* mode , timer controll */
1243 		FMSetMode( &(OPN->ST),OPN->ST.index,v );
1244 		break;
1245 	case 0x28:	/* key on / off */
1246 		c = v&0x03;
1247 		if( c == 3 ) break;
1248 		if( (v&0x04) && (OPN->type & TYPE_6CH) ) c+=3;
1249 		CH = OPN->P_CH;
1250 		CH = &CH[c];
1251 		/* csm mode */
1252 		/* if( c == 2 && (OPN->ST.mode & 0x80) ) break; */
1253 		if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
1254 		if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
1255 		if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
1256 		if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
1257 /*		LOG(LOG_INF,("OPN %d:%d : KEY %02X\n",n,c,v&0xf0));*/
1258 		break;
1259 	}
1260 }
1261 
1262 /* ---------- write a OPN register (0x30-0xff) ---------- */
OPNWriteReg(FM_OPN * OPN,int r,int v)1263 static void OPNWriteReg(FM_OPN *OPN, int r, int v)
1264 {
1265 	UINT8 c;
1266 	FM_CH *CH;
1267 	FM_SLOT *SLOT;
1268 
1269 	/* 0x30 - 0xff */
1270 	if( (c = OPN_CHAN(r)) == 3 ) return; /* 0xX3,0xX7,0xXB,0xXF */
1271 	if( (r >= 0x100) /* && (OPN->type & TYPE_6CH) */ ) c+=3;
1272 		CH = OPN->P_CH;
1273 		CH = &CH[c];
1274 
1275 	SLOT = &(CH->SLOT[OPN_SLOT(r)]);
1276 	switch( r & 0xf0 ) {
1277 	case 0x30:	/* DET , MUL */
1278 		set_det_mul(&OPN->ST,CH,SLOT,v);
1279 		break;
1280 	case 0x40:	/* TL */
1281 		set_tl(CH,SLOT,v,(c == 2) && (OPN->ST.mode & 0x80) );
1282 		break;
1283 	case 0x50:	/* KS, AR */
1284 		set_ar_ksr(CH,SLOT,v,OPN->ST.AR_TABLE);
1285 		break;
1286 	case 0x60:	/*     DR */
1287 		/* bit7 = AMS_ON ENABLE(YM2612) */
1288 		set_dr(SLOT,v,OPN->ST.DR_TABLE);
1289 #if FM_LFO_SUPPORT
1290 		if( OPN->type & TYPE_LFOPAN)
1291 		{
1292 			SLOT->amon = v>>7;
1293 			SLOT->ams = CH->ams * SLOT->amon;
1294 		}
1295 #endif
1296 		break;
1297 	case 0x70:	/*     SR */
1298 		set_sr(SLOT,v,OPN->ST.DR_TABLE);
1299 		break;
1300 	case 0x80:	/* SL, RR */
1301 		set_sl_rr(SLOT,v,OPN->ST.DR_TABLE);
1302 		break;
1303 	case 0x90:	/* SSG-EG */
1304 #if !FM_SEG_SUPPORT
1305 		if(v&0x08) LOG(LOG_ERR,("OPN %d,%d,%d :SSG-TYPE envelope selected (not supported )\n",OPN->ST.index,c,OPN_SLOT(r)));
1306 #endif
1307 		SLOT->SEG = v&0x0f;
1308 		break;
1309 	case 0xa0:
1310 		switch( OPN_SLOT(r) ){
1311 		case 0:		/* 0xa0-0xa2 : FNUM1 */
1312 			{
1313 				UINT32 fn  = (((UINT32)( (CH->fn_h)&7))<<8) + v;
1314 				UINT8 blk = CH->fn_h>>3;
1315 				/* make keyscale code */
1316 				CH->kcode = (blk<<2)|OPN_FKTABLE[(fn>>7)];
1317 				/* make basic increment counter 32bit = 1 cycle */
1318 				CH->fc = OPN->FN_TABLE[fn]>>(7-blk);
1319 				CH->SLOT[SLOT1].Incr=-1;
1320 			}
1321 			break;
1322 		case 1:		/* 0xa4-0xa6 : FNUM2,BLK */
1323 			CH->fn_h = v&0x3f;
1324 			break;
1325 		case 2:		/* 0xa8-0xaa : 3CH FNUM1 */
1326 			if( r < 0x100)
1327 			{
1328 				UINT32 fn  = (((UINT32)(OPN->SL3.fn_h[c]&7))<<8) + v;
1329 				UINT8 blk = OPN->SL3.fn_h[c]>>3;
1330 				/* make keyscale code */
1331 				OPN->SL3.kcode[c]= (blk<<2)|OPN_FKTABLE[(fn>>7)];
1332 				/* make basic increment counter 32bit = 1 cycle */
1333 				OPN->SL3.fc[c] = OPN->FN_TABLE[fn]>>(7-blk);
1334 				(OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
1335 			}
1336 			break;
1337 		case 3:		/* 0xac-0xae : 3CH FNUM2,BLK */
1338 			if( r < 0x100)
1339 				OPN->SL3.fn_h[c] = v&0x3f;
1340 			break;
1341 		}
1342 		break;
1343 	case 0xb0:
1344 		switch( OPN_SLOT(r) ){
1345 		case 0:		/* 0xb0-0xb2 : FB,ALGO */
1346 			{
1347 				int feedback = (v>>3)&7;
1348 				CH->ALGO = v&7;
1349 				CH->FB   = feedback ? 8+1 - feedback : 0;
1350 				setup_connection( CH );
1351 			}
1352 			break;
1353 		case 1:		/* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2608) */
1354 			if( OPN->type & TYPE_LFOPAN)
1355 			{
1356 #if FM_LFO_SUPPORT
1357 				/* b0-2 PMS */
1358 				/* 0,3.4,6.7,10,14,20,40,80(cent) */
1359 				static const float pmd_table[8]={0,3.4,6.7,10,14,20,40,80};
1360 				static const int amd_table[4]={(int)(0/EG_STEP),(int)(1.4/EG_STEP),(int)(5.9/EG_STEP),(int)(11.8/EG_STEP) };
1361 				CH->pms = (INT32)( (1.5/1200.0)*pmd_table[v & 7] * PMS_RATE);
1362 				/* b4-5 AMS */
1363 				/* 0 , 1.4 , 5.9 , 11.8(dB) */
1364 				CH->ams = amd_table[(v>>4) & 0x03];
1365 				CH->SLOT[SLOT1].ams = CH->ams * CH->SLOT[SLOT1].amon;
1366 				CH->SLOT[SLOT2].ams = CH->ams * CH->SLOT[SLOT2].amon;
1367 				CH->SLOT[SLOT3].ams = CH->ams * CH->SLOT[SLOT3].amon;
1368 				CH->SLOT[SLOT4].ams = CH->ams * CH->SLOT[SLOT4].amon;
1369 #endif
1370 				/* PAN */
1371 				CH->PAN = (v>>6)&0x03; /* PAN : b6 = R , b7 = L */
1372 				setup_connection( CH );
1373 				/* LOG(LOG_INF,("OPN %d,%d : PAN %d\n",n,c,CH->PAN));*/
1374 			}
1375 			break;
1376 		}
1377 		break;
1378 	}
1379 }
1380 #endif /* BUILD_OPN */
1381 
1382 #if BUILD_YM2203
1383 /*******************************************************************************/
1384 /*		YM2203 local section                                                   */
1385 /*******************************************************************************/
1386 
1387 /* here's the virtual YM2203(OPN) */
1388 typedef struct ym2203_f {
1389 	FM_OPN OPN;				/* OPN state         */
1390 	FM_CH CH[3];			/* channel state     */
1391 } YM2203;
1392 
1393 static YM2203 *FM2203=NULL;	/* array of YM2203's */
1394 static int YM2203NumChips;	/* total chip */
1395 
1396 /* ---------- update one of chip ----------- */
YM2203UpdateOne(int num,INT16 * buffer,int length)1397 void YM2203UpdateOne(int num, INT16 *buffer, int length)
1398 {
1399 	YM2203 *F2203 = &(FM2203[num]);
1400 	FM_OPN *OPN =   &(FM2203[num].OPN);
1401 	int i;
1402 	FM_CH *ch;
1403 	FMSAMPLE *buf = buffer;
1404 
1405 	cur_chip = (void *)F2203;
1406 	State = &F2203->OPN.ST;
1407 	cch[0]   = &F2203->CH[0];
1408 	cch[1]   = &F2203->CH[1];
1409 	cch[2]   = &F2203->CH[2];
1410 #if FM_LFO_SUPPORT
1411 	/* LFO */
1412 	lfo_amd = lfo_pmd = 0;
1413 #endif
1414 	/* frequency counter channel A */
1415 	OPN_CALC_FCOUNT( cch[0] );
1416 	/* frequency counter channel B */
1417 	OPN_CALC_FCOUNT( cch[1] );
1418 	/* frequency counter channel C */
1419 	if( (State->mode & 0xc0) ){
1420 		/* 3SLOT MODE */
1421 		if( cch[2]->SLOT[SLOT1].Incr==-1){
1422 			/* 3 slot mode */
1423 			CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
1424 			CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
1425 			CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
1426 			CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
1427 		}
1428 	}else OPN_CALC_FCOUNT( cch[2] );
1429 
1430     for (i=0;i<length;i++)
1431 	{
1432 		/*            channel A         channel B         channel C      */
1433 		out_ch[OUTD_CENTER] = 0;
1434 		/* calcrate FM */
1435 		for( ch=cch[0] ; ch <= cch[2] ; ch++)
1436 			FM_CALC_CH( ch );
1437 		/* limit check */
1438 		Limit( out_ch[OUTD_CENTER] , FM_MAXOUT, FM_MINOUT );
1439 		/* store to sound buffer */
1440 		buf[i] = out_ch[OUTD_CENTER] >> FM_OUTSB;
1441 		/* timer controll */
1442 		INTERNAL_TIMER_A( State , cch[2] )
1443 	}
1444 	INTERNAL_TIMER_B(State,length)
1445 }
1446 
1447 /* ---------- reset one of chip ---------- */
YM2203ResetChip(int num)1448 void YM2203ResetChip(int num)
1449 {
1450 	int i;
1451 	FM_OPN *OPN = &(FM2203[num].OPN);
1452 
1453 	/* Reset Priscaler */
1454 	OPNSetPris( OPN , 6*12 , 6*12 ,4); /* 1/6 , 1/4 */
1455 	/* reset SSG section */
1456 	SSGReset(OPN->ST.index);
1457 	/* status clear */
1458 	FM_IRQMASK_SET(&OPN->ST,0x03);
1459 	OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
1460 	reset_channel( &OPN->ST , FM2203[num].CH , 3 );
1461 	/* reset OPerator paramater */
1462 	for(i = 0xb6 ; i >= 0xb4 ; i-- ) OPNWriteReg(OPN,i,0xc0); /* PAN RESET */
1463 	for(i = 0xb2 ; i >= 0x30 ; i-- ) OPNWriteReg(OPN,i,0);
1464 	for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
1465 }
1466 
1467 /* ----------  Initialize YM2203 emulator(s) ----------    */
1468 /* 'num' is the number of virtual YM2203's to allocate     */
1469 /* 'rate' is sampling rate and 'bufsiz' is the size of the */
1470 /* buffer that should be updated at each interval          */
YM2203Init(int num,int clock,int rate,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)1471 int YM2203Init(int num, int clock, int rate,
1472                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
1473 {
1474 	int i;
1475 
1476 	if (FM2203) return (-1);	/* duplicate init. */
1477 	cur_chip = NULL;	/* hiro-shi!! */
1478 
1479 	YM2203NumChips = num;
1480 
1481 	/* allocate ym2203 state space */
1482 	if( (FM2203 = (YM2203 *)malloc(sizeof(YM2203) * YM2203NumChips))==NULL)
1483 		return (-1);
1484 	/* clear */
1485 	memset(FM2203,0,sizeof(YM2203) * YM2203NumChips);
1486 	/* allocate total level table (128kb space) */
1487 	if( !OPNInitTable() )
1488 	{
1489 		free( FM2203 );
1490 		return (-1);
1491 	}
1492 	for ( i = 0 ; i < YM2203NumChips; i++ ) {
1493 		FM2203[i].OPN.ST.index = i;
1494 		FM2203[i].OPN.type = TYPE_YM2203;
1495 		FM2203[i].OPN.P_CH = FM2203[i].CH;
1496 		FM2203[i].OPN.ST.clock = clock;
1497 		FM2203[i].OPN.ST.rate = rate;
1498 		/* FM2203[i].OPN.ST.irq = 0; */
1499 		/* FM2203[i].OPN.ST.satus = 0; */
1500 		FM2203[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
1501 		/* Extend handler */
1502 		FM2203[i].OPN.ST.Timer_Handler = TimerHandler;
1503 		FM2203[i].OPN.ST.IRQ_Handler   = IRQHandler;
1504 		YM2203ResetChip(i);
1505 	}
1506 	return(0);
1507 }
1508 
1509 /* ---------- shut down emurator ----------- */
YM2203Shutdown(void)1510 void YM2203Shutdown(void)
1511 {
1512     if (!FM2203) return;
1513 
1514 	FMCloseTable();
1515 	free(FM2203);
1516 	FM2203 = NULL;
1517 }
1518 
1519 /* ---------- YM2203 I/O interface ---------- */
YM2203Write(int n,int a,UINT8 v)1520 int YM2203Write(int n,int a,UINT8 v)
1521 {
1522 	FM_OPN *OPN = &(FM2203[n].OPN);
1523 
1524 	if( !(a&1) )
1525 	{	/* address port */
1526 		OPN->ST.address = v & 0xff;
1527 		/* Write register to SSG emurator */
1528 		if( v < 16 ) SSGWrite(n,0,v);
1529 		switch(OPN->ST.address)
1530 		{
1531 		case 0x2d:	/* divider sel */
1532 			OPNSetPris( OPN, 6*12, 6*12 ,4); /* OPN 1/6 , SSG 1/4 */
1533 			break;
1534 		case 0x2e:	/* divider sel */
1535 			OPNSetPris( OPN, 3*12, 3*12,2); /* OPN 1/3 , SSG 1/2 */
1536 			break;
1537 		case 0x2f:	/* divider sel */
1538 			OPNSetPris( OPN, 2*12, 2*12,1); /* OPN 1/2 , SSG 1/1 */
1539 			break;
1540 		}
1541 	}
1542 	else
1543 	{	/* data port */
1544 		int addr = OPN->ST.address;
1545 		switch( addr & 0xf0 )
1546 		{
1547 		case 0x00:	/* 0x00-0x0f : SSG section */
1548 			/* Write data to SSG emurator */
1549 			SSGWrite(n,a,v);
1550 			break;
1551 		case 0x20:	/* 0x20-0x2f : Mode section */
1552 			YM2203UpdateReq(n);
1553 			/* write register */
1554 			 OPNWriteMode(OPN,addr,v);
1555 			break;
1556 		default:	/* 0x30-0xff : OPN section */
1557 			YM2203UpdateReq(n);
1558 			/* write register */
1559 			 OPNWriteReg(OPN,addr,v);
1560 		}
1561 	}
1562 	return OPN->ST.irq;
1563 }
1564 
YM2203Read(int n,int a)1565 UINT8 YM2203Read(int n,int a)
1566 {
1567 	YM2203 *F2203 = &(FM2203[n]);
1568 	int addr = F2203->OPN.ST.address;
1569 	int ret = 0;
1570 
1571 	if( !(a&1) )
1572 	{	/* status port */
1573 		ret = F2203->OPN.ST.status;
1574 	}
1575 	else
1576 	{	/* data port (ONLY SSG) */
1577 		if( addr < 16 ) ret = SSGRead(n);
1578 	}
1579 	return ret;
1580 }
1581 
YM2203TimerOver(int n,int c)1582 int YM2203TimerOver(int n,int c)
1583 {
1584 	YM2203 *F2203 = &(FM2203[n]);
1585 
1586 	if( c )
1587 	{	/* Timer B */
1588 		TimerBOver( &(F2203->OPN.ST) );
1589 	}
1590 	else
1591 	{	/* Timer A */
1592 		YM2203UpdateReq(n);
1593 		/* timer update */
1594 		TimerAOver( &(F2203->OPN.ST) );
1595 		/* CSM mode key,TL controll */
1596 		if( F2203->OPN.ST.mode & 0x80 )
1597 		{	/* CSM mode total level latch and auto key on */
1598 			CSMKeyControll( &(F2203->CH[2]) );
1599 		}
1600 	}
1601 	return F2203->OPN.ST.irq;
1602 }
1603 
1604 #endif /* BUILD_YM2203 */
1605 
1606 #if (BUILD_YM2608||BUILD_OPNB)
1607 /* adpcm type A struct */
1608 typedef struct adpcm_state {
1609 	UINT8 flag;			/* port state        */
1610 	UINT8 flagMask;		/* arrived flag mask */
1611 	UINT8 now_data;
1612 	UINT32 now_addr;
1613 	UINT32 now_step;
1614 	UINT32 step;
1615 	UINT32 start;
1616 	UINT32 end;
1617 	int IL;
1618 	int volume;					/* calcrated mixing level */
1619 	INT32 *pan;					/* &out_ch[OPN_xxxx] */
1620 	int /*adpcmm,*/ adpcmx, adpcmd;
1621 	int adpcml;					/* hiro-shi!! */
1622 }ADPCM_CH;
1623 
1624 /* here's the virtual YM2610 */
1625 typedef struct ym2610_f {
1626 	FM_OPN OPN;				/* OPN state    */
1627 	FM_CH CH[6];			/* channel state */
1628 	int address1;			/* address register1 */
1629 	/* ADPCM-A unit */
1630 	UINT8 *pcmbuf;			/* pcm rom buffer */
1631 	UINT32 pcm_size;			/* size of pcm rom */
1632 	INT32 *adpcmTL;					/* adpcmA total level */
1633 	ADPCM_CH adpcm[6];				/* adpcm channels */
1634 	UINT32 adpcmreg[0x30];	/* registers */
1635 	UINT8 adpcm_arrivedEndAddress;
1636 	/* Delta-T ADPCM unit */
1637 	YM_DELTAT deltaT;
1638 } YM2610;
1639 
1640 /* here's the virtual YM2608 */
1641 typedef YM2610 YM2608;
1642 #endif /* (BUILD_YM2608||BUILD_OPNB) */
1643 
1644 #if BUILD_FM_ADPCMA
1645 /***************************************************************/
1646 /*    ADPCMA units are made by Hiromitsu Shioya (MMSND)         */
1647 /***************************************************************/
1648 
1649 /**** YM2610 ADPCM defines ****/
1650 #define ADPCMA_MIXING_LEVEL  (3) /* ADPCMA mixing level   */
1651 #define ADPCM_SHIFT    (16)      /* frequency step rate   */
1652 #define ADPCMA_ADDRESS_SHIFT 8   /* adpcm A address shift */
1653 
1654 //#define ADPCMA_DECODE_RANGE 1024
1655 #define ADPCMA_DECODE_RANGE 2048
1656 #define ADPCMA_DECODE_MIN (-(ADPCMA_DECODE_RANGE*ADPCMA_MIXING_LEVEL))
1657 #define ADPCMA_DECODE_MAX ((ADPCMA_DECODE_RANGE*ADPCMA_MIXING_LEVEL)-1)
1658 #define ADPCMA_VOLUME_DIV 1
1659 
1660 static UINT8 *pcmbufA;
1661 static UINT32 pcmsizeA;
1662 
1663 /************************************************************/
1664 /************************************************************/
1665 /* --------------------- subroutines  --------------------- */
1666 /************************************************************/
1667 /************************************************************/
1668 /************************/
1669 /*    ADPCM A tables    */
1670 /************************/
1671 static int jedi_table[(48+1)*16];
1672 static int decode_tableA1[16] = {
1673   -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
1674   -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
1675 };
1676 
1677 /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
1678 /* 8 = -1 , 2 5 8 11 */
1679 /* 9 = -1 , 2 5 9 13 */
1680 /* 10= -1 , 2 6 10 14 */
1681 /* 12= -1 , 2 7 12 17 */
1682 /* 20= -2 , 4 12 20 32 */
1683 
1684 #if 1
InitOPNB_ADPCMATable(void)1685 static void InitOPNB_ADPCMATable(void){
1686 	int step, nib;
1687 
1688 	for (step = 0; step <= 48; step++)
1689 	{
1690 		float stepval = floor(16.0 * pow (11.0 / 10.0, (double)step) * ADPCMA_MIXING_LEVEL);
1691 		/* loop over all nibbles and compute the difference */
1692 		for (nib = 0; nib < 16; nib++)
1693 		{
1694 			int value = (int)stepval*((nib&0x07)*2+1)/8;
1695 			jedi_table[step*16+nib] = (nib&0x08) ? -value : value;
1696 		}
1697 	}
1698 }
1699 #else
1700 static int decode_tableA2[49] = {
1701   0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001c, 0x001f,
1702   0x0022, 0x0025, 0x0029, 0x002d, 0x0032, 0x0037, 0x003c, 0x0042,
1703   0x0049, 0x0050, 0x0058, 0x0061, 0x006b, 0x0076, 0x0082, 0x008f,
1704   0x009d, 0x00ad, 0x00be, 0x00d1, 0x00e6, 0x00fd, 0x0117, 0x0133,
1705   0x0151, 0x0173, 0x0198, 0x01c1, 0x01ee, 0x0220, 0x0256, 0x0292,
1706   0x02d4, 0x031c, 0x036c, 0x03c3, 0x0424, 0x048e, 0x0502, 0x0583,
1707   0x0610
1708 };
InitOPNB_ADPCMATable(void)1709 static void InitOPNB_ADPCMATable(void){
1710    int ta,tb,tc;
1711    for(ta=0;ta<49;ta++){
1712      for(tb=0;tb<16;tb++){
1713        tc=0;
1714        if(tb&0x04){tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL));}
1715        if(tb&0x02){tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL)>>1);}
1716        if(tb&0x01){tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL)>>2);}
1717        tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL)>>3);
1718        if(tb&0x08){tc=(0-tc);}
1719        jedi_table[ta*16+tb]=tc;
1720      }
1721    }
1722 }
1723 #endif
1724 
1725 /**** ADPCM A (Non control type) ****/
OPNB_ADPCM_CALC_CHA(YM2610 * F2610,ADPCM_CH * ch)1726 static INLINE void OPNB_ADPCM_CALC_CHA( YM2610 *F2610, ADPCM_CH *ch )
1727 {
1728 	UINT32 step;
1729 	int data;
1730 
1731 	ch->now_step += ch->step;
1732 	if ( ch->now_step >= (1<<ADPCM_SHIFT) )
1733 	{
1734 		step = ch->now_step >> ADPCM_SHIFT;
1735 		ch->now_step &= (1<<ADPCM_SHIFT)-1;
1736 		/* end check */
1737 		if ( (ch->now_addr+step) > (ch->end<<1) ) {
1738 			ch->flag = 0;
1739 			F2610->adpcm_arrivedEndAddress |= ch->flagMask;
1740 			return;
1741 		}
1742 		do{
1743 #if 0
1744 			if ( ch->now_addr > (pcmsizeA<<1) ) {
1745 				LOG(LOG_WAR,("YM2610: Attempting to play past adpcm rom size!\n" ));
1746 				return;
1747 			}
1748 #endif
1749 			if( ch->now_addr&1 ) data = ch->now_data & 0x0f;
1750 			else
1751 			{
1752 				ch->now_data = *(pcmbufA+(ch->now_addr>>1));
1753 				data = (ch->now_data >> 4)&0x0f;
1754 			}
1755 			ch->now_addr++;
1756 
1757 			ch->adpcmx += jedi_table[ch->adpcmd+data];
1758 			Limit( ch->adpcmx,ADPCMA_DECODE_MAX, ADPCMA_DECODE_MIN );
1759 			ch->adpcmd += decode_tableA1[data];
1760 			Limit( ch->adpcmd, 48*16, 0*16 );
1761 			/**** calc pcm * volume data ****/
1762 			ch->adpcml = ch->adpcmx * ch->volume;
1763 		}while(--step);
1764 	}
1765 	/* output for work of output channels (out_ch[OPNxxxx])*/
1766 	*(ch->pan) += ch->adpcml;
1767 }
1768 
1769 /* ADPCM type A */
FM_ADPCMAWrite(YM2610 * F2610,int r,int v)1770 static void FM_ADPCMAWrite(YM2610 *F2610,int r,int v)
1771 {
1772 	ADPCM_CH *adpcm = F2610->adpcm;
1773 	UINT8 c = r&0x07;
1774 
1775 	F2610->adpcmreg[r] = v&0xff; /* stock data */
1776 	switch( r ){
1777 	case 0x00: /* DM,--,C5,C4,C3,C2,C1,C0 */
1778 		/* F2610->port1state = v&0xff; */
1779 		if( !(v&0x80) ){
1780 			/* KEY ON */
1781 			for( c = 0; c < 6; c++ ){
1782 				if( (1<<c)&v ){
1783 					/**** start adpcm ****/
1784 					adpcm[c].step     = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/3.0);
1785 					adpcm[c].now_addr = adpcm[c].start<<1;
1786 					adpcm[c].now_step = (1<<ADPCM_SHIFT)-adpcm[c].step;
1787 					/*adpcm[c].adpcmm   = 0;*/
1788 					adpcm[c].adpcmx   = 0;
1789 					adpcm[c].adpcmd   = 0;
1790 					adpcm[c].adpcml   = 0;
1791 					adpcm[c].flag     = 1;
1792 					if(F2610->pcmbuf==NULL){			// Check ROM Mapped
1793 						LOG(LOG_WAR,("YM2610: ADPCM-A rom not mapped\n"));
1794 						adpcm[c].flag = 0;
1795 					} else{
1796 						if(adpcm[c].end >= F2610->pcm_size){		// Check End in Range
1797 							LOG(LOG_WAR,("YM2610: ADPCM-A end out of range: $%08x\n",adpcm[c].end));
1798 							adpcm[c].end = F2610->pcm_size-1;
1799 						}
1800 						if(adpcm[c].start >= F2610->pcm_size)
1801 						{	// Check Start in Range
1802 							LOG(LOG_WAR,("YM2610: ADPCM-A start out of range: $%08x\n",adpcm[c].start));
1803 							adpcm[c].flag = 0;
1804 						}
1805 /*LOG(LOG_WAR,("YM2610: Start %06X : %02X %02X %02X\n",adpcm[c].start,
1806 pcmbufA[adpcm[c].start],pcmbufA[adpcm[c].start+1],pcmbufA[adpcm[c].start+2]));*/
1807 					}
1808 				}	/*** (1<<c)&v ***/
1809 			}	/**** for loop ****/
1810 		} else{
1811 			/* KEY OFF */
1812 			for( c = 0; c < 6; c++ ){
1813 				if( (1<<c)&v )  adpcm[c].flag = 0;
1814 			}
1815 		}
1816 		break;
1817 	case 0x01:	/* B0-5 = TL 0.75dB step */
1818 		F2610->adpcmTL = &(TL_TABLE[((v&0x3f)^0x3f)*(int)(0.75/EG_STEP)]);
1819 		for( c = 0; c < 6; c++ )
1820 		{
1821 			adpcm[c].volume = F2610->adpcmTL[adpcm[c].IL*(int)(0.75/EG_STEP)] / ADPCMA_DECODE_RANGE / ADPCMA_VOLUME_DIV;
1822 			/**** calc pcm * volume data ****/
1823 			adpcm[c].adpcml = adpcm[c].adpcmx * adpcm[c].volume;
1824 		}
1825 		break;
1826 	default:
1827 		c = r&0x07;
1828 		if( c >= 0x06 ) return;
1829 		switch( r&0x38 ){
1830 		case 0x08:	/* B7=L,B6=R,B4-0=IL */
1831 			adpcm[c].IL = (v&0x1f)^0x1f;
1832 			adpcm[c].volume = F2610->adpcmTL[adpcm[c].IL*(int)(0.75/EG_STEP)] / ADPCMA_DECODE_RANGE / ADPCMA_VOLUME_DIV;
1833 			adpcm[c].pan    = &out_ch[(v>>6)&0x03];
1834 			/**** calc pcm * volume data ****/
1835 			adpcm[c].adpcml = adpcm[c].adpcmx * adpcm[c].volume;
1836 			break;
1837 		case 0x10:
1838 		case 0x18:
1839 			adpcm[c].start  = ( (F2610->adpcmreg[0x18 + c]*0x0100 | F2610->adpcmreg[0x10 + c]) << ADPCMA_ADDRESS_SHIFT);
1840 			break;
1841 		case 0x20:
1842 		case 0x28:
1843 			adpcm[c].end    = ( (F2610->adpcmreg[0x28 + c]*0x0100 | F2610->adpcmreg[0x20 + c]) << ADPCMA_ADDRESS_SHIFT);
1844 			adpcm[c].end   += (1<<ADPCMA_ADDRESS_SHIFT) - 1;
1845 			break;
1846 		}
1847 	}
1848 }
1849 
1850 #endif /* BUILD_FM_ADPCMA */
1851 
1852 #if BUILD_YM2608
1853 /*******************************************************************************/
1854 /*		YM2608 local section                                                   */
1855 /*******************************************************************************/
1856 static YM2608 *FM2608=NULL;	/* array of YM2608's */
1857 static int YM2608NumChips;	/* total chip */
1858 
1859 /* YM2608 Rhythm Number */
1860 #define RY_BD  0
1861 #define RY_SD  1
1862 #define RY_TOP 2
1863 #define RY_HH  3
1864 #define RY_TOM 4
1865 #define RY_RIM 5
1866 
1867 #if 0
1868 /* Get next pcm data */
1869 static INLINE int YM2608ReadADPCM(int n)
1870 {
1871 	YM2608 *F2608 = &(FM2608[n]);
1872 	if( F2608->ADMode & 0x20 )
1873 	{	/* buffer memory */
1874 		/* F2203->OPN.ST.status |= 0x04; */
1875 		return 0;
1876 	}
1877 	else
1878 	{	/* from PCM data register */
1879 		FM_STATUS_SET(F2608->OPN.ST,0x08); /* BRDY = 1 */
1880 		return F2608->ADData;
1881 	}
1882 }
1883 
1884 /* Put decoded data */
1885 static INLINE void YM2608WriteADPCM(int n,int v)
1886 {
1887 	YM2608 *F2608 = &(FM2608[n]);
1888 	if( F2608->ADMode & 0x20 )
1889 	{	/* for buffer */
1890 		return;
1891 	}
1892 	else
1893 	{	/* for PCM data port */
1894 		F2608->ADData = v;
1895 		FM_STATUS_SET(F2608->OPN.ST,0x08) /* BRDY = 1 */
1896 	}
1897 }
1898 #endif
1899 
1900 /* ---------- IRQ flag Controll Write 0x110 ---------- */
YM2608IRQFlagWrite(FM_ST * ST,int n,int v)1901 static INLINE void YM2608IRQFlagWrite(FM_ST *ST,int n,int v)
1902 {
1903 	if( v & 0x80 )
1904 	{	/* Reset IRQ flag */
1905 		FM_STATUS_RESET(ST,0xff);
1906 	}
1907 	else
1908 	{	/* Set IRQ mask */
1909 		/* !!!!!!!!!! pending !!!!!!!!!! */
1910 	}
1911 }
1912 
1913 #ifdef YM2608_RHYTHM_PCM
1914 /**** RYTHM (PCM) ****/
YM2608_RYTHM(YM2608 * F2608,ADPCM_CH * ch)1915 static INLINE void YM2608_RYTHM( YM2608 *F2608, ADPCM_CH *ch )
1916 
1917 {
1918 	UINT32 step;
1919 
1920 	ch->now_step += ch->step;
1921 	if ( ch->now_step >= (1<<ADPCM_SHIFT) )
1922 	{
1923 		step = ch->now_step >> ADPCM_SHIFT;
1924 		ch->now_step &= (1<<ADPCM_SHIFT)-1;
1925 		/* end check */
1926 		if ( (ch->now_addr+step) > (ch->end<<1) ) {
1927 			ch->flag = 0;
1928 			F2608->adpcm_arrivedEndAddress |= ch->flagMask;
1929 			return;
1930 		}
1931 		do{
1932 			/* get a next pcm data */
1933 			ch->adpcmx = ((short *)pcmbufA)[ch->now_addr];
1934 			ch->now_addr++;
1935 			/**** calc pcm * volume data ****/
1936 			ch->adpcml = ch->adpcmx * ch->volume;
1937 		}while(--step);
1938 	}
1939 	/* output for work of output channels (out_ch[OPNxxxx])*/
1940 	*(ch->pan) += ch->adpcml;
1941 }
1942 #endif /* YM2608_RHYTHM_PCM */
1943 
1944 /* ---------- update one of chip ----------- */
YM2608UpdateOne(int num,INT16 ** buffer,int length)1945 void YM2608UpdateOne(int num, INT16 **buffer, int length)
1946 {
1947 	YM2608 *F2608 = &(FM2608[num]);
1948 	FM_OPN *OPN   = &(FM2608[num].OPN);
1949 	YM_DELTAT *DELTAT = &(F2608[num].deltaT);
1950 	int j;
1951 	FM_CH *ch;
1952 	FMSAMPLE  *bufL,*bufR;
1953 
1954 	/* setup DELTA-T unit */
1955 	YM_DELTAT_DECODE_PRESET(DELTAT);
1956 	DELTAT->arrivedFlag = 0;	/* ASG */
1957 	DELTAT->flagMask = 1;	/* ASG */
1958 
1959 	/* set bufer */
1960 	bufL = buffer[0];
1961 	bufR = buffer[1];
1962 
1963 	if( (void *)F2608 != cur_chip ){
1964 		cur_chip = (void *)F2608;
1965 
1966 		State = &OPN->ST;
1967 		cch[0]   = &F2608->CH[0];
1968 		cch[1]   = &F2608->CH[1];
1969 		cch[2]   = &F2608->CH[2];
1970 		cch[3]   = &F2608->CH[3];
1971 		cch[4]   = &F2608->CH[4];
1972 		cch[5]   = &F2608->CH[5];
1973 		/* setup adpcm rom address */
1974 		pcmbufA  = F2608->pcmbuf;
1975 		pcmsizeA = F2608->pcm_size;
1976 #if FM_LFO_SUPPORT
1977 		LFOCnt  = OPN->LFOCnt;
1978 		LFOIncr = OPN->LFOIncr;
1979 		if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
1980 #endif
1981 	}
1982 	/* update frequency counter */
1983 	OPN_CALC_FCOUNT( cch[0] );
1984 	OPN_CALC_FCOUNT( cch[1] );
1985 	if( (State->mode & 0xc0) ){
1986 		/* 3SLOT MODE */
1987 		if( cch[2]->SLOT[SLOT1].Incr==-1){
1988 			/* 3 slot mode */
1989 			CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
1990 			CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
1991 			CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
1992 			CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
1993 		}
1994 	}else OPN_CALC_FCOUNT( cch[2] );
1995 	OPN_CALC_FCOUNT( cch[3] );
1996 	OPN_CALC_FCOUNT( cch[4] );
1997 	OPN_CALC_FCOUNT( cch[5] );
1998 	/* buffering */
1999     do
2000 	{
2001 #if FM_LFO_SUPPORT
2002 		/* LFO */
2003 		if( LFOIncr )
2004 		{
2005 			lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2006 			lfo_pmd = lfo_amd-(LFO_RATE/2);
2007 		}
2008 #endif
2009 		/* clear output acc. */
2010 		out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2011 		/**** deltaT ADPCM ****/
2012 		if( DELTAT->flag )
2013 			YM_DELTAT_ADPCM_CALC(DELTAT);
2014 		/* FM */
2015 		for(ch = cch[0] ; ch <= cch[5] ; ch++)
2016 			FM_CALC_CH( ch );
2017 		for( j = 0; j < 6; j++ )
2018 		{
2019 			/**** ADPCM ****/
2020 			if( F2608->adpcm[j].flag )
2021 #ifdef YM2608_RHYTHM_PCM
2022 				YM2608_RYTHM(F2608, &F2608->adpcm[j]);
2023 #else
2024 				OPNB_ADPCM_CALC_CHA( F2608, &F2608->adpcm[j]);
2025 #endif
2026 		}
2027 		/* buffering */
2028 		FM_BUFFERING_STEREO;
2029 		/* timer A controll */
2030 		INTERNAL_TIMER_A( State , cch[2] )
2031 	}
2032 	while (--length);
2033 	INTERNAL_TIMER_B(State,length)
2034 	if (DELTAT->arrivedFlag) FM_STATUS_SET(State, 0x04);	/* ASG */
2035 
2036 #if FM_LFO_SUPPORT
2037 	OPN->LFOCnt = LFOCnt;
2038 #endif
2039 }
2040 
2041 /* -------------------------- YM2608(OPNA) ---------------------------------- */
YM2608Init(int num,int clock,int rate,void ** pcmrom,int * pcmsize,short * rhythmrom,int * rhythmpos,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)2042 int YM2608Init(int num, int clock, int rate,
2043                void **pcmrom,int *pcmsize,short *rhythmrom,int *rhythmpos,
2044                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2045 {
2046 	int i,j;
2047 
2048     if (FM2608) return (-1);	/* duplicate init. */
2049     cur_chip = NULL;	/* hiro-shi!! */
2050 
2051 	YM2608NumChips = num;
2052 
2053 	/* allocate extend state space */
2054 	if( (FM2608 = (YM2608 *)malloc(sizeof(YM2608) * YM2608NumChips))==NULL)
2055 		return (-1);
2056 	/* clear */
2057 	memset(FM2608,0,sizeof(YM2608) * YM2608NumChips);
2058 	/* allocate total level table (128kb space) */
2059 	if( !OPNInitTable() )
2060 	{
2061 		free( FM2608 );
2062 		return (-1);
2063 	}
2064 
2065 	for ( i = 0 ; i < YM2608NumChips; i++ ) {
2066 		FM2608[i].OPN.ST.index = i;
2067 		FM2608[i].OPN.type = TYPE_YM2608;
2068 		FM2608[i].OPN.P_CH = FM2608[i].CH;
2069 		FM2608[i].OPN.ST.clock = clock;
2070 		FM2608[i].OPN.ST.rate = rate;
2071 		/* FM2608[i].OPN.ST.irq = 0; */
2072 		/* FM2608[i].OPN.ST.status = 0; */
2073 		FM2608[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
2074 		/* Extend handler */
2075 		FM2608[i].OPN.ST.Timer_Handler = TimerHandler;
2076 		FM2608[i].OPN.ST.IRQ_Handler   = IRQHandler;
2077 		/* DELTA-T */
2078 		FM2608[i].deltaT.memory = (UINT8 *)(pcmrom[i]);
2079 		FM2608[i].deltaT.memory_size = pcmsize[i];
2080 		/* ADPCM(Rythm) */
2081 		FM2608[i].pcmbuf   = (UINT8 *)rhythmrom;
2082 #ifdef YM2608_RHYTHM_PCM
2083 		/* rhythm sound setup (PCM) */
2084 		for(j=0;j<6;j++)
2085 		{
2086 			/* rhythm sound */
2087 			FM2608[i].adpcm[j].start = rhythmpos[j];
2088 			FM2608[i].adpcm[j].end   = rhythmpos[j+1]-1;
2089 		}
2090 		FM2608[i].pcm_size = rhythmpos[6];
2091 #else
2092 		/* rhythm sound setup (ADPCM) */
2093 		FM2608[i].pcm_size = rhythmsize;
2094 #endif
2095 		YM2608ResetChip(i);
2096 	}
2097 	InitOPNB_ADPCMATable();
2098 	return 0;
2099 }
2100 
2101 /* ---------- shut down emurator ----------- */
YM2608Shutdown()2102 void YM2608Shutdown()
2103 {
2104     if (!FM2608) return;
2105 
2106 	FMCloseTable();
2107 	free(FM2608);
2108 	FM2608 = NULL;
2109 }
2110 
2111 /* ---------- reset one of chip ---------- */
YM2608ResetChip(int num)2112 void YM2608ResetChip(int num)
2113 {
2114 	int i;
2115 	YM2608 *F2608 = &(FM2608[num]);
2116 	FM_OPN *OPN   = &(FM2608[num].OPN);
2117 	YM_DELTAT *DELTAT = &(F2608[num].deltaT);
2118 
2119 	/* Reset Priscaler */
2120 	OPNSetPris( OPN, 6*24, 6*24,4*2); /* OPN 1/6 , SSG 1/4 */
2121 	/* reset SSG section */
2122 	SSGReset(OPN->ST.index);
2123 	/* status clear */
2124 	FM_IRQMASK_SET(&OPN->ST,0x1f);
2125 	OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2126 
2127 	/* extend 3ch. disable */
2128 	//OPN->type &= (~TYPE_6CH);
2129 
2130 	reset_channel( &OPN->ST , F2608->CH , 6 );
2131 	/* reset OPerator paramater */
2132 	for(i = 0xb6 ; i >= 0xb4 ; i-- )
2133 	{
2134 		OPNWriteReg(OPN,i      ,0xc0);
2135 		OPNWriteReg(OPN,i|0x100,0xc0);
2136 	}
2137 	for(i = 0xb2 ; i >= 0x30 ; i-- )
2138 	{
2139 		OPNWriteReg(OPN,i      ,0);
2140 		OPNWriteReg(OPN,i|0x100,0);
2141 	}
2142 	for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2143 	/* reset ADPCM unit */
2144 	/**** ADPCM work initial ****/
2145 	//for( i = 0; i < 6+1; i++ ){
2146 	for( i = 0; i < 6; i++ ){
2147 		F2608->adpcm[i].now_addr  = 0;
2148 		F2608->adpcm[i].now_step  = 0;
2149 		F2608->adpcm[i].step      = 0;
2150 		F2608->adpcm[i].start     = 0;
2151 		F2608->adpcm[i].end       = 0;
2152 		/* F2608->adpcm[i].delta     = 21866; */
2153 		F2608->adpcm[i].volume    = 0;
2154 		F2608->adpcm[i].pan       = &out_ch[OUTD_CENTER]; /* default center */
2155 		F2608->adpcm[i].flagMask  = (i == 6) ? 0x20 : 0;
2156 		F2608->adpcm[i].flag      = 0;
2157 		F2608->adpcm[i].adpcmx    = 0;
2158 		F2608->adpcm[i].adpcmd    = 127;
2159 		F2608->adpcm[i].adpcml    = 0;
2160 	}
2161 	F2608->adpcmTL = &(TL_TABLE[0x3f*(int)(0.75/EG_STEP)]);
2162 	/* F2608->port1state = -1; */
2163 	F2608->adpcm_arrivedEndAddress = 0; /* don't used */
2164 
2165 	/* DELTA-T unit */
2166 	DELTAT->freqbase = OPN->ST.freqbase;
2167 	DELTAT->output_pointer = out_ch;
2168 	DELTAT->portshift = 5;		/* allways 5bits shift */ /* ASG */
2169 	DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
2170 	YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER);
2171 }
2172 
2173 /* YM2608 write */
2174 /* n = number  */
2175 /* a = address */
2176 /* v = value   */
YM2608Write(int n,int a,UINT8 v)2177 int YM2608Write(int n, int a,UINT8 v)
2178 {
2179 	YM2608 *F2608 = &(FM2608[n]);
2180 	FM_OPN *OPN   = &(FM2608[n].OPN);
2181 	int addr;
2182 
2183 	switch(a&3){
2184 	case 0:	/* address port 0 */
2185 		OPN->ST.address = v & 0xff;
2186 		/* Write register to SSG emurator */
2187 		if( v < 16 ) SSGWrite(n,0,v);
2188 		switch(OPN->ST.address)
2189 		{
2190 		case 0x2d:	/* divider sel */
2191 			OPNSetPris( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
2192 			F2608->deltaT.freqbase = OPN->ST.freqbase;
2193 			break;
2194 		case 0x2e:	/* divider sel */
2195 			OPNSetPris( OPN, 3*24, 3*24,2*2); /* OPN 1/3 , SSG 1/2 */
2196 			F2608->deltaT.freqbase = OPN->ST.freqbase;
2197 			break;
2198 		case 0x2f:	/* divider sel */
2199 			OPNSetPris( OPN, 2*24, 2*24,1*2); /* OPN 1/2 , SSG 1/1 */
2200 			F2608->deltaT.freqbase = OPN->ST.freqbase;
2201 			break;
2202 		}
2203 		break;
2204 	case 1:	/* data port 0    */
2205 		addr = OPN->ST.address;
2206 		switch(addr & 0xf0)
2207 		{
2208 		case 0x00:	/* SSG section */
2209 			/* Write data to SSG emurator */
2210 			SSGWrite(n,a,v);
2211 			break;
2212 		case 0x10:	/* 0x10-0x1f : Rhythm section */
2213 #ifndef MAME_FASTSOUND
2214 			YM2608UpdateReq(n);
2215 #else
2216 			if (!fast_sound) YM2608UpdateReq(n);
2217 #endif
2218 			FM_ADPCMAWrite(F2608,addr-0x10,v);
2219 			break;
2220 		case 0x20:	/* Mode Register */
2221 			switch(addr)
2222 			{
2223 			case 0x29: /* SCH,xirq mask */
2224 				/* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
2225 				/* extend 3ch. enable/disable */
2226 				if(v&0x80) OPN->type |= TYPE_6CH;
2227 				else       OPN->type &= ~TYPE_6CH;
2228 				/* IRQ MASK */
2229 				FM_IRQMASK_SET(&OPN->ST,v&0x1f);
2230 				break;
2231 			default:
2232 #ifndef MAME_FASTSOUND
2233 				YM2608UpdateReq(n);
2234 #else
2235 				if (!fast_sound) YM2608UpdateReq(n);
2236 #endif
2237 				OPNWriteMode(OPN,addr,v);
2238 			}
2239 			break;
2240 		default:	/* OPN section */
2241 #ifndef MAME_FASTSOUND
2242 			YM2608UpdateReq(n);
2243 #else
2244 			if (!fast_sound) YM2608UpdateReq(n);
2245 #endif
2246 			OPNWriteReg(OPN,addr,v);
2247 		}
2248 		break;
2249 	case 2:	/* address port 1 */
2250 		F2608->address1 = v & 0xff;
2251 		break;
2252 	case 3:	/* data port 1    */
2253 		addr = F2608->address1;
2254 #ifndef MAME_FASTSOUND
2255 		YM2608UpdateReq(n);
2256 #else
2257 		if (!fast_sound) YM2608UpdateReq(n);
2258 #endif
2259 		switch( addr & 0xf0 )
2260 		{
2261 		case 0x00:	/* ADPCM PORT */
2262 			switch( addr )
2263 			{
2264 			case 0x0c:	/* Limit address L */
2265 				//F2608->ADLimit = (F2608->ADLimit & 0xff00) | v;
2266 				//break;
2267 			case 0x0d:	/* Limit address H */
2268 				//F2608->ADLimit = (F2608->ADLimit & 0x00ff) | (v<<8);
2269 				//break;
2270 			case 0x0e:	/* DAC data */
2271 				//break;
2272 			case 0x0f:	/* PCM data port */
2273 				//F2608->ADData = v;
2274 				//FM_STATUS_RESET(F2608->OPN.ST,0x08);
2275 				break;
2276 			default:
2277 				/* 0x00-0x0b */
2278 				YM_DELTAT_ADPCM_Write(&F2608->deltaT,addr,v);
2279 			}
2280 			break;
2281 		case 0x10:	/* IRQ Flag controll */
2282 			if( addr == 0x10 )
2283 				YM2608IRQFlagWrite(&(OPN->ST),n,v);
2284 			break;
2285 		default:
2286 			OPNWriteReg(OPN,addr|0x100,v);
2287 		}
2288 	}
2289 	return OPN->ST.irq;
2290 }
YM2608Read(int n,int a)2291 UINT8 YM2608Read(int n,int a)
2292 {
2293 	YM2608 *F2608 = &(FM2608[n]);
2294 	int addr = F2608->OPN.ST.address;
2295 	int ret = 0;
2296 
2297 	switch( a&3 ){
2298 	case 0:	/* status 0 : YM2203 compatible */
2299 		/* BUSY:x:x:x:x:x:FLAGB:FLAGA */
2300 		if(addr==0xff) ret = 0x00; /* ID code */
2301 		else ret = F2608->OPN.ST.status & 0x83;
2302 		break;
2303 	case 1:	/* status 0 */
2304 		if( addr < 16 ) ret = SSGRead(n);
2305 		break;
2306 	case 2:	/* status 1 : + ADPCM status */
2307 		/* BUSY:x:PCMBUSY:ZERO:BRDY:EOS:FLAGB:FLAGA */
2308 		if(addr==0xff) ret = 0x00; /* ID code */
2309 		//else ret = F2608->OPN.ST.status | (F2608->adpcm[6].flag ? 0x20 : 0);
2310 		else ret = F2608->OPN.ST.status | (F2608->adpcm[5].flag ? 0x20 : 0);
2311 		break;
2312 	case 3:
2313 		ret = 0;
2314 		break;
2315 	}
2316 	return ret;
2317 }
2318 
YM2608TimerOver(int n,int c)2319 int YM2608TimerOver(int n,int c)
2320 {
2321 	YM2608 *F2608 = &(FM2608[n]);
2322 
2323 	if( c )
2324 	{	/* Timer B */
2325 		TimerBOver( &(F2608->OPN.ST) );
2326 	}
2327 	else
2328 	{	/* Timer A */
2329 		YM2608UpdateReq(n);
2330 		/* timer update */
2331 		TimerAOver( &(F2608->OPN.ST) );
2332 		/* CSM mode key,TL controll */
2333 		if( F2608->OPN.ST.mode & 0x80 )
2334 		{	/* CSM mode total level latch and auto key on */
2335 			CSMKeyControll( &(F2608->CH[2]) );
2336 		}
2337 	}
2338 	return FM2608->OPN.ST.irq;
2339 }
2340 
2341 #endif /* BUILD_YM2608 */
2342 
2343 #if BUILD_OPNB
2344 /* -------------------------- YM2610(OPNB) ---------------------------------- */
2345 static YM2610 *FM2610=NULL;	/* array of YM2610's */
2346 static int YM2610NumChips;	/* total chip */
2347 
2348 /* ---------- update one of chip (YM2610B FM6: ADPCM-A6: ADPCM-B:1) ----------- */
YM2610UpdateOne(int num,INT16 ** buffer,int length)2349 void YM2610UpdateOne(int num, INT16 **buffer, int length)
2350 {
2351 	YM2610 *F2610 = &(FM2610[num]);
2352 	FM_OPN *OPN   = &(FM2610[num].OPN);
2353 	YM_DELTAT *DELTAT = &(F2610[num].deltaT);
2354 	int j;
2355 	int ch;
2356 	FMSAMPLE  *bufL,*bufR;
2357 
2358 	/* setup DELTA-T unit */
2359 	YM_DELTAT_DECODE_PRESET(DELTAT);
2360 
2361 	/* buffer setup */
2362 	bufL = buffer[0];
2363 	bufR = buffer[1];
2364 
2365 	if( (void *)F2610 != cur_chip ){
2366 		cur_chip = (void *)F2610;
2367 		State = &OPN->ST;
2368 		cch[0] = &F2610->CH[1];
2369 		cch[1] = &F2610->CH[2];
2370 		cch[2] = &F2610->CH[4];
2371 		cch[3] = &F2610->CH[5];
2372 		/* setup adpcm rom address */
2373 		pcmbufA  = F2610->pcmbuf;
2374 		pcmsizeA = F2610->pcm_size;
2375 #if FM_LFO_SUPPORT
2376 		LFOCnt  = OPN->LFOCnt;
2377 		LFOIncr = OPN->LFOIncr;
2378 		if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
2379 #endif
2380 	}
2381 #ifdef YM2610B_WARNING
2382 #define FM_MSG_YM2610B "YM2610-%d.CH%d is playing,Check whether the type of the chip is YM2610B\n"
2383 	/* Check YM2610B worning message */
2384 	if( FM_KEY_IS(&F2610->CH[0].SLOT[3]) )
2385 		LOG(LOG_WAR,(FM_MSG_YM2610B,num,0));
2386 	if( FM_KEY_IS(&F2610->CH[3].SLOT[3]) )
2387 		LOG(LOG_WAR,(FM_MSG_YM2610B,num,3));
2388 #endif
2389 	/* update frequency counter */
2390 	OPN_CALC_FCOUNT( cch[0] );
2391 	if( (State->mode & 0xc0) ){
2392 		/* 3SLOT MODE */
2393 		if( cch[1]->SLOT[SLOT1].Incr==-1){
2394 			/* 3 slot mode */
2395 			CALC_FCSLOT(&cch[1]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2396 			CALC_FCSLOT(&cch[1]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2397 			CALC_FCSLOT(&cch[1]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2398 			CALC_FCSLOT(&cch[1]->SLOT[SLOT4] , cch[1]->fc , cch[1]->kcode );
2399 		}
2400 	}else OPN_CALC_FCOUNT( cch[1] );
2401 	OPN_CALC_FCOUNT( cch[2] );
2402 	OPN_CALC_FCOUNT( cch[3] );
2403 
2404 	/* buffering */
2405     do
2406 	{
2407 #if FM_LFO_SUPPORT
2408 		/* LFO */
2409 		if( LFOIncr )
2410 		{
2411 			lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2412 			lfo_pmd = lfo_amd-(LFO_RATE/2);
2413 		}
2414 #endif
2415 		/* clear output acc. */
2416 		out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2417 		/**** deltaT ADPCM ****/
2418 		if( DELTAT->flag )
2419 			YM_DELTAT_ADPCM_CALC(DELTAT);
2420 		/* FM */
2421 		for(ch = 0 ; ch < 4 ; ch++)
2422 			FM_CALC_CH( cch[ch] );
2423 		for( j = 0; j < 6; j++ )
2424 		{
2425 			/**** ADPCM ****/
2426 			if( F2610->adpcm[j].flag )
2427 				OPNB_ADPCM_CALC_CHA( F2610, &F2610->adpcm[j]);
2428 		}
2429 		/* buffering */
2430 		FM_BUFFERING_STEREO;
2431 		/* timer A controll */
2432 		INTERNAL_TIMER_A( State , cch[1] )
2433 	}
2434 	while (--length);
2435 	INTERNAL_TIMER_B(State,length)
2436 #if FM_LFO_SUPPORT
2437 	OPN->LFOCnt = LFOCnt;
2438 #endif
2439 }
2440 #endif /* BUILD_OPNB */
2441 
2442 #if BUILD_YM2610B
2443 /* ---------- update one of chip (YM2610B FM6: ADPCM-A6: ADPCM-B:1) ----------- */
YM2610BUpdateOne(int num,INT16 ** buffer,int length)2444 void YM2610BUpdateOne(int num, INT16 **buffer, int length)
2445 {
2446 	YM2610 *F2610 = &(FM2610[num]);
2447 	FM_OPN *OPN   = &(FM2610[num].OPN);
2448 	YM_DELTAT *DELTAT = &(FM2610[num].deltaT);
2449 	int j;
2450 	FM_CH *ch;
2451 	FMSAMPLE  *bufL,*bufR;
2452 
2453 	/* setup DELTA-T unit */
2454 	YM_DELTAT_DECODE_PRESET(DELTAT);
2455 	/* buffer setup */
2456 	bufL = buffer[0];
2457 	bufR = buffer[1];
2458 
2459 	if( (void *)F2610 != cur_chip ){
2460 		cur_chip = (void *)F2610;
2461 		State = &OPN->ST;
2462 		cch[0] = &F2610->CH[0];
2463 		cch[1] = &F2610->CH[1];
2464 		cch[2] = &F2610->CH[2];
2465 		cch[3] = &F2610->CH[3];
2466 		cch[4] = &F2610->CH[4];
2467 		cch[5] = &F2610->CH[5];
2468 		/* setup adpcm rom address */
2469 		pcmbufA  = F2610->pcmbuf;
2470 		pcmsizeA = F2610->pcm_size;
2471 #if FM_LFO_SUPPORT
2472 		LFOCnt  = OPN->LFOCnt;
2473 		LFOIncr = OPN->LFOIncr;
2474 		if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
2475 #endif
2476 	}
2477 
2478 	/* update frequency counter */
2479 	OPN_CALC_FCOUNT( cch[0] );
2480 	OPN_CALC_FCOUNT( cch[1] );
2481 	if( (State->mode & 0xc0) ){
2482 		/* 3SLOT MODE */
2483 		if( cch[2]->SLOT[SLOT1].Incr==-1){
2484 			/* 3 slot mode */
2485 			CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2486 			CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2487 			CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2488 			CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2489 		}
2490 	}else OPN_CALC_FCOUNT( cch[2] );
2491 	OPN_CALC_FCOUNT( cch[3] );
2492 	OPN_CALC_FCOUNT( cch[4] );
2493 	OPN_CALC_FCOUNT( cch[5] );
2494 
2495 	/* buffering */
2496     do
2497 	{
2498 #if FM_LFO_SUPPORT
2499 		/* LFO */
2500 		if( LFOIncr )
2501 		{
2502 			lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2503 			lfo_pmd = lfo_amd-(LFO_RATE/2);
2504 		}
2505 #endif
2506 		/* clear output acc. */
2507 		out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2508 		/**** deltaT ADPCM ****/
2509 		if( DELTAT->flag )
2510 			YM_DELTAT_ADPCM_CALC(DELTAT);
2511 		/* FM */
2512 		for(ch = cch[0] ; ch <= cch[5] ; ch++)
2513 			FM_CALC_CH( ch );
2514 		for( j = 0; j < 6; j++ )
2515 		{
2516 			/**** ADPCM ****/
2517 			if( F2610->adpcm[j].flag )
2518 				OPNB_ADPCM_CALC_CHA( F2610, &F2610->adpcm[j]);
2519 		}
2520 		/* buffering */
2521 		FM_BUFFERING_STEREO;
2522 		/* timer A controll */
2523 		INTERNAL_TIMER_A( State , cch[2] )
2524 	}
2525 	while (--length);
2526 	INTERNAL_TIMER_B(State,length)
2527 #if FM_LFO_SUPPORT
2528 	OPN->LFOCnt = LFOCnt;
2529 #endif
2530 }
2531 #endif /* BUILD_YM2610B */
2532 
2533 #if BUILD_OPNB
YM2610Init(int num,int clock,int rate,void ** pcmroma,int * pcmsizea,void ** pcmromb,int * pcmsizeb,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)2534 int YM2610Init(int num, int clock, int rate,
2535                void **pcmroma,int *pcmsizea,void **pcmromb,int *pcmsizeb,
2536                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2537 
2538 {
2539 	int i;
2540 
2541     if (FM2610) return (-1);	/* duplicate init. */
2542     cur_chip = NULL;	/* hiro-shi!! */
2543 
2544 	YM2610NumChips = num;
2545 
2546 	/* allocate extend state space */
2547 	if( (FM2610 = (YM2610 *)malloc(sizeof(YM2610) * YM2610NumChips))==NULL)
2548 		return (-1);
2549 	/* clear */
2550 	memset(FM2610,0,sizeof(YM2610) * YM2610NumChips);
2551 	/* allocate total level table (128kb space) */
2552 	if( !OPNInitTable() )
2553 	{
2554 		free( FM2610 );
2555 		return (-1);
2556 	}
2557 
2558 	for ( i = 0 ; i < YM2610NumChips; i++ ) {
2559 		/* FM */
2560 		FM2610[i].OPN.ST.index = i;
2561 		FM2610[i].OPN.type = TYPE_YM2610;
2562 		FM2610[i].OPN.P_CH = FM2610[i].CH;
2563 		FM2610[i].OPN.ST.clock = clock;
2564 		FM2610[i].OPN.ST.rate = rate;
2565 		/* FM2610[i].OPN.ST.irq = 0; */
2566 		/* FM2610[i].OPN.ST.status = 0; */
2567 		FM2610[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
2568 		/* Extend handler */
2569 		FM2610[i].OPN.ST.Timer_Handler = TimerHandler;
2570 		FM2610[i].OPN.ST.IRQ_Handler   = IRQHandler;
2571 		/* ADPCM */
2572 		FM2610[i].pcmbuf   = (UINT8 *)(pcmroma[i]);
2573 		FM2610[i].pcm_size = pcmsizea[i];
2574 		/* DELTA-T */
2575 		FM2610[i].deltaT.memory = (UINT8 *)(pcmromb[i]);
2576 		FM2610[i].deltaT.memory_size = pcmsizeb[i];
2577 		/* */
2578 		YM2610ResetChip(i);
2579 	}
2580 	InitOPNB_ADPCMATable();
2581 	return 0;
2582 }
2583 
2584 /* ---------- shut down emurator ----------- */
YM2610Shutdown()2585 void YM2610Shutdown()
2586 {
2587     if (!FM2610) return;
2588 
2589 	FMCloseTable();
2590 	free(FM2610);
2591 	FM2610 = NULL;
2592 }
2593 
2594 /* ---------- reset one of chip ---------- */
YM2610ResetChip(int num)2595 void YM2610ResetChip(int num)
2596 {
2597 	int i;
2598 	YM2610 *F2610 = &(FM2610[num]);
2599 	FM_OPN *OPN   = &(FM2610[num].OPN);
2600 	YM_DELTAT *DELTAT = &(FM2610[num].deltaT);
2601 
2602 	/* Reset Priscaler */
2603 	OPNSetPris( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
2604 	/* reset SSG section */
2605 	SSGReset(OPN->ST.index);
2606 	/* status clear */
2607 	FM_IRQMASK_SET(&OPN->ST,0x03);
2608 	OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2609 
2610 	reset_channel( &OPN->ST , F2610->CH , 6 );
2611 	/* reset OPerator paramater */
2612 	for(i = 0xb6 ; i >= 0xb4 ; i-- )
2613 	{
2614 		OPNWriteReg(OPN,i      ,0xc0);
2615 		OPNWriteReg(OPN,i|0x100,0xc0);
2616 	}
2617 	for(i = 0xb2 ; i >= 0x30 ; i-- )
2618 	{
2619 		OPNWriteReg(OPN,i      ,0);
2620 		OPNWriteReg(OPN,i|0x100,0);
2621 	}
2622 	for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2623 	/**** ADPCM work initial ****/
2624 	//for( i = 0; i < 6+1; i++ ){
2625 	for( i = 0; i < 6; i++ ){
2626 		F2610->adpcm[i].now_addr  = 0;
2627 		F2610->adpcm[i].now_step  = 0;
2628 		F2610->adpcm[i].step      = 0;
2629 		F2610->adpcm[i].start     = 0;
2630 		F2610->adpcm[i].end       = 0;
2631 		/* F2610->adpcm[i].delta     = 21866; */
2632 		F2610->adpcm[i].volume    = 0;
2633 		F2610->adpcm[i].pan       = &out_ch[OUTD_CENTER]; /* default center */
2634 		F2610->adpcm[i].flagMask  = (i == 6) ? 0x80 : (1<<i);
2635 		F2610->adpcm[i].flag      = 0;
2636 		F2610->adpcm[i].adpcmx    = 0;
2637 		F2610->adpcm[i].adpcmd    = 127;
2638 		F2610->adpcm[i].adpcml    = 0;
2639 	}
2640 	F2610->adpcmTL = &(TL_TABLE[0x3f*(int)(0.75/EG_STEP)]);
2641 	/* F2610->port1state = -1; */
2642 	F2610->adpcm_arrivedEndAddress = 0;
2643 
2644 	/* DELTA-T unit */
2645 	DELTAT->freqbase = OPN->ST.freqbase;
2646 	DELTAT->output_pointer = out_ch;
2647 	DELTAT->portshift = 8;		/* allways 8bits shift */
2648 	DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
2649 	YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER);
2650 }
2651 
2652 /* YM2610 write */
2653 /* n = number  */
2654 /* a = address */
2655 /* v = value   */
YM2610Write(int n,int a,UINT8 v)2656 int YM2610Write(int n, int a,UINT8 v)
2657 {
2658 	YM2610 *F2610 = &(FM2610[n]);
2659 	FM_OPN *OPN   = &(FM2610[n].OPN);
2660 	int addr;
2661 	int ch;
2662 
2663 	switch( a&3 ){
2664 	case 0:	/* address port 0 */
2665 		OPN->ST.address = v & 0xff;
2666 		/* Write register to SSG emurator */
2667 		if( v < 16 ) SSGWrite(n,0,v);
2668 		break;
2669 	case 1:	/* data port 0    */
2670 		addr = OPN->ST.address;
2671 		switch(addr & 0xf0)
2672 		{
2673 		case 0x00:	/* SSG section */
2674 			/* Write data to SSG emurator */
2675 			SSGWrite(n,a,v);
2676 			break;
2677 		case 0x10: /* DeltaT ADPCM */
2678 #ifndef MAME_FASTSOUND
2679 			YM2610UpdateReq(n);
2680 #else
2681 			if (!fast_sound) YM2610UpdateReq(n);
2682 #endif
2683 			switch(addr)
2684 			{
2685 			case 0x1c: /*  FLAG CONTROL : Extend Status Clear/Mask */
2686 			{
2687 				UINT8 statusmask = ~v;
2688 				/* set arrived flag mask */
2689 				for(ch=0;ch<6;ch++)
2690 					F2610->adpcm[ch].flagMask = statusmask&(1<<ch);
2691 				F2610->deltaT.flagMask = statusmask&0x80;
2692 				/* clear arrived flag */
2693 				F2610->adpcm_arrivedEndAddress &= statusmask&0x3f;
2694 				F2610->deltaT.arrivedFlag      &= F2610->deltaT.flagMask;
2695 			}
2696 				break;
2697 			default:
2698 				/* 0x10-0x1b */
2699 				YM_DELTAT_ADPCM_Write(&F2610->deltaT,addr-0x10,v);
2700 			}
2701 			break;
2702 		case 0x20:	/* Mode Register */
2703 #ifndef MAME_FASTSOUND
2704 			YM2610UpdateReq(n);
2705 #else
2706 			if (!fast_sound) YM2610UpdateReq(n);
2707 #endif
2708 			OPNWriteMode(OPN,addr,v);
2709 			break;
2710 		default:	/* OPN section */
2711 #ifndef MAME_FASTSOUND
2712 			YM2610UpdateReq(n);
2713 #else
2714 			if (!fast_sound) YM2610UpdateReq(n);
2715 #endif
2716 			/* write register */
2717 			 OPNWriteReg(OPN,addr,v);
2718 		}
2719 		break;
2720 	case 2:	/* address port 1 */
2721 		F2610->address1 = v & 0xff;
2722 		break;
2723 	case 3:	/* data port 1    */
2724 #ifndef MAME_FASTSOUND
2725 		YM2610UpdateReq(n);
2726 #else
2727 		if (!fast_sound) YM2610UpdateReq(n);
2728 #endif
2729 		addr = F2610->address1;
2730 		if( addr < 0x30 )
2731 			/* 100-12f : ADPCM A section */
2732 			FM_ADPCMAWrite(F2610,addr,v);
2733 		else
2734 			OPNWriteReg(OPN,addr|0x100,v);
2735 	}
2736 	return OPN->ST.irq;
2737 }
YM2610Read(int n,int a)2738 UINT8 YM2610Read(int n,int a)
2739 {
2740 	YM2610 *F2610 = &(FM2610[n]);
2741 	int addr = F2610->OPN.ST.address;
2742 	UINT8 ret = 0;
2743 
2744 	switch( a&3){
2745 	case 0:	/* status 0 : YM2203 compatible */
2746 		ret = F2610->OPN.ST.status & 0x83;
2747 		break;
2748 	case 1:	/* data 0 */
2749 		if( addr < 16 ) ret = SSGRead(n);
2750 		if( addr == 0xff ) ret = 0x01;
2751 		break;
2752 	case 2:	/* status 1 : + ADPCM status */
2753 		/* ADPCM STATUS (arrived End Address) */
2754 		/* B,--,A5,A4,A3,A2,A1,A0 */
2755 		/* B     = ADPCM-B(DELTA-T) arrived end address */
2756 		/* A0-A5 = ADPCM-A          arrived end address */
2757 		ret = F2610->adpcm_arrivedEndAddress | F2610->deltaT.arrivedFlag;
2758 		break;
2759 	case 3:
2760 		ret = 0;
2761 		break;
2762 	}
2763 	return ret;
2764 }
2765 
YM2610TimerOver(int n,int c)2766 int YM2610TimerOver(int n,int c)
2767 {
2768 	YM2610 *F2610 = &(FM2610[n]);
2769 
2770 	if( c )
2771 	{	/* Timer B */
2772 		TimerBOver( &(F2610->OPN.ST) );
2773 	}
2774 	else
2775 	{	/* Timer A */
2776 		YM2610UpdateReq(n);
2777 		/* timer update */
2778 		TimerAOver( &(F2610->OPN.ST) );
2779 		/* CSM mode key,TL controll */
2780 		if( F2610->OPN.ST.mode & 0x80 )
2781 		{	/* CSM mode total level latch and auto key on */
2782 			CSMKeyControll( &(F2610->CH[2]) );
2783 		}
2784 	}
2785 	return F2610->OPN.ST.irq;
2786 }
2787 
2788 #endif /* BUILD_OPNB */
2789 
2790 
2791 #if BUILD_YM2612
2792 /*******************************************************************************/
2793 /*		YM2612 local section                                                   */
2794 /*******************************************************************************/
2795 /* here's the virtual YM2612 */
2796 typedef struct ym2612_f {
2797 	FM_OPN OPN;						/* OPN state       */
2798 	FM_CH CH[6];					/* channel state */
2799 	int address1;	/* address register1 */
2800 	/* dac output (YM2612) */
2801 	int dacen;
2802 	int dacout;
2803 } YM2612;
2804 
2805 static int YM2612NumChips;	/* total chip */
2806 static YM2612 *FM2612=NULL;	/* array of YM2612's */
2807 
2808 static int dacen;
2809 
2810 /* ---------- update one of chip ----------- */
YM2612UpdateOne(int num,INT16 ** buffer,int length)2811 void YM2612UpdateOne(int num, INT16 **buffer, int length)
2812 {
2813 	YM2612 *F2612 = &(FM2612[num]);
2814 	FM_OPN *OPN   = &(FM2612[num].OPN);
2815 	FM_CH *ch,*ech;
2816 	FMSAMPLE  *bufL,*bufR;
2817 	int dacout  = F2612->dacout;
2818 
2819 	/* set bufer */
2820 	bufL = buffer[0];
2821 	bufR = buffer[1];
2822 
2823 	if( (void *)F2612 != cur_chip ){
2824 		cur_chip = (void *)F2612;
2825 
2826 		State = &OPN->ST;
2827 		cch[0]   = &F2612->CH[0];
2828 		cch[1]   = &F2612->CH[1];
2829 		cch[2]   = &F2612->CH[2];
2830 		cch[3]   = &F2612->CH[3];
2831 		cch[4]   = &F2612->CH[4];
2832 		cch[5]   = &F2612->CH[5];
2833 		/* DAC mode */
2834 		dacen = F2612->dacen;
2835 #if FM_LFO_SUPPORT
2836 		LFOCnt  = OPN->LFOCnt;
2837 		LFOIncr = OPN->LFOIncr;
2838 		if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
2839 #endif
2840 	}
2841 	/* update frequency counter */
2842 	OPN_CALC_FCOUNT( cch[0] );
2843 	OPN_CALC_FCOUNT( cch[1] );
2844 	if( (State->mode & 0xc0) ){
2845 		/* 3SLOT MODE */
2846 		if( cch[2]->SLOT[SLOT1].Incr==-1){
2847 			/* 3 slot mode */
2848 			CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2849 			CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2850 			CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2851 			CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2852 		}
2853 	}else OPN_CALC_FCOUNT( cch[2] );
2854 	OPN_CALC_FCOUNT( cch[3] );
2855 	OPN_CALC_FCOUNT( cch[4] );
2856 	OPN_CALC_FCOUNT( cch[5] );
2857 
2858 	ech = dacen ? cch[4] : cch[5];
2859 	/* buffering */
2860     do
2861 	{
2862 #if FM_LFO_SUPPORT
2863 		/* LFO */
2864 		if( LFOIncr )
2865 		{
2866 			lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2867 			lfo_pmd = lfo_amd-(LFO_RATE/2);
2868 		}
2869 #endif
2870 		/* clear output acc. */
2871 		out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2872 		/* calcrate channel output */
2873 		for(ch = cch[0] ; ch <= ech ; ch++)
2874 			FM_CALC_CH( ch );
2875 		if( dacen )  *cch[5]->connect4 += dacout;
2876 		/* buffering */
2877 		FM_BUFFERING_STEREO;
2878 		/* timer A controll */
2879 		INTERNAL_TIMER_A( State , cch[2] )
2880 	}
2881 	while (--length);
2882 	INTERNAL_TIMER_B(State,length)
2883 #if FM_LFO_SUPPORT
2884 	OPN->LFOCnt = LFOCnt;
2885 #endif
2886 }
2887 
2888 /* -------------------------- YM2612 ---------------------------------- */
YM2612Init(int num,int clock,int rate,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)2889 int YM2612Init(int num, int clock, int rate,
2890                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2891 {
2892 	int i;
2893 
2894     if (FM2612) return (-1);	/* duplicate init. */
2895     cur_chip = NULL;	/* hiro-shi!! */
2896 
2897 	YM2612NumChips = num;
2898 
2899 	/* allocate extend state space */
2900 	if( (FM2612 = (YM2612 *)malloc(sizeof(YM2612) * YM2612NumChips))==NULL)
2901 		return (-1);
2902 	/* clear */
2903 	memset(FM2612,0,sizeof(YM2612) * YM2612NumChips);
2904 	/* allocate total level table (128kb space) */
2905 	if( !OPNInitTable() )
2906 	{
2907 		free( FM2612 );
2908 		return (-1);
2909 	}
2910 
2911 	for ( i = 0 ; i < YM2612NumChips; i++ ) {
2912 		FM2612[i].OPN.ST.index = i;
2913 		FM2612[i].OPN.type = TYPE_YM2612;
2914 		FM2612[i].OPN.P_CH = FM2612[i].CH;
2915 		FM2612[i].OPN.ST.clock = clock;
2916 		FM2612[i].OPN.ST.rate = rate;
2917 		/* FM2612[i].OPN.ST.irq = 0; */
2918 		/* FM2612[i].OPN.ST.status = 0; */
2919 		FM2612[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
2920 		/* Extend handler */
2921 		FM2612[i].OPN.ST.Timer_Handler = TimerHandler;
2922 		FM2612[i].OPN.ST.IRQ_Handler   = IRQHandler;
2923 		YM2612ResetChip(i);
2924 	}
2925 	return 0;
2926 }
2927 
2928 /* ---------- shut down emurator ----------- */
YM2612Shutdown()2929 void YM2612Shutdown()
2930 {
2931     if (!FM2612) return;
2932 
2933 	FMCloseTable();
2934 	free(FM2612);
2935 	FM2612 = NULL;
2936 }
2937 
2938 /* ---------- reset one of chip ---------- */
YM2612ResetChip(int num)2939 void YM2612ResetChip(int num)
2940 {
2941 	int i;
2942 	YM2612 *F2612 = &(FM2612[num]);
2943 	FM_OPN *OPN   = &(FM2612[num].OPN);
2944 
2945 	OPNSetPris( OPN , 12*12, 12*12, 0);
2946 	/* status clear */
2947 	FM_IRQMASK_SET(&OPN->ST,0x03);
2948 	OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2949 
2950 	reset_channel( &OPN->ST , &F2612->CH[0] , 6 );
2951 
2952 	for(i = 0xb6 ; i >= 0xb4 ; i-- )
2953 	{
2954 		OPNWriteReg(OPN,i      ,0xc0);
2955 		OPNWriteReg(OPN,i|0x100,0xc0);
2956 	}
2957 	for(i = 0xb2 ; i >= 0x30 ; i-- )
2958 	{
2959 		OPNWriteReg(OPN,i      ,0);
2960 		OPNWriteReg(OPN,i|0x100,0);
2961 	}
2962 	for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2963 	/* DAC mode clear */
2964 	F2612->dacen = 0;
2965 }
2966 
2967 /* YM2612 write */
2968 /* n = number  */
2969 /* a = address */
2970 /* v = value   */
YM2612Write(int n,int a,UINT8 v)2971 int YM2612Write(int n, int a,UINT8 v)
2972 {
2973 	YM2612 *F2612 = &(FM2612[n]);
2974 	int addr;
2975 
2976 	switch( a&3){
2977 	case 0:	/* address port 0 */
2978 		F2612->OPN.ST.address = v & 0xff;
2979 		break;
2980 	case 1:	/* data port 0    */
2981 		addr = F2612->OPN.ST.address;
2982 		switch( addr & 0xf0 )
2983 		{
2984 		case 0x20:	/* 0x20-0x2f Mode */
2985 			switch( addr )
2986 			{
2987 			case 0x2a:	/* DAC data (YM2612) */
2988 #ifndef MAME_FASTSOUND
2989 				YM2612UpdateReq(n);
2990 #else
2991 				if (!fast_sound) YM2612UpdateReq(n);
2992 #endif
2993 				F2612->dacout = ((int)v - 0x80)<<(TL_BITS-7);
2994 				break;
2995 			case 0x2b:	/* DAC Sel  (YM2612) */
2996 				/* b7 = dac enable */
2997 				F2612->dacen = v & 0x80;
2998 				cur_chip = NULL;
2999 				break;
3000 			default:	/* OPN section */
3001 #ifndef MAME_FASTSOUND
3002 				YM2612UpdateReq(n);
3003 #else
3004 				if (!fast_sound) YM2612UpdateReq(n);
3005 #endif
3006 				/* write register */
3007 				 OPNWriteMode(&(F2612->OPN),addr,v);
3008 			}
3009 			break;
3010 		default:	/* 0x30-0xff OPN section */
3011 #ifndef MAME_FASTSOUND
3012 			YM2612UpdateReq(n);
3013 #else
3014 			if (!fast_sound) YM2612UpdateReq(n);
3015 #endif
3016 			/* write register */
3017 			 OPNWriteReg(&(F2612->OPN),addr,v);
3018 		}
3019 		break;
3020 	case 2:	/* address port 1 */
3021 		F2612->address1 = v & 0xff;
3022 		break;
3023 	case 3:	/* data port 1    */
3024 		addr = F2612->address1;
3025 #ifndef MAME_FASTSOUND
3026 		YM2612UpdateReq(n);
3027 #else
3028 		if (!fast_sound) YM2612UpdateReq(n);
3029 #endif
3030 		OPNWriteReg(&(F2612->OPN),addr|0x100,v);
3031 		break;
3032 	}
3033 	return F2612->OPN.ST.irq;
3034 }
YM2612Read(int n,int a)3035 UINT8 YM2612Read(int n,int a)
3036 {
3037 	YM2612 *F2612 = &(FM2612[n]);
3038 
3039 	switch( a&3){
3040 	case 0:	/* status 0 */
3041 		return F2612->OPN.ST.status;
3042 	case 1:
3043 	case 2:
3044 	case 3:
3045 		LOG(LOG_WAR,("YM2612 #%d:A=%d read unmapped area\n"));
3046 		return F2612->OPN.ST.status;
3047 	}
3048 	return 0;
3049 }
3050 
YM2612TimerOver(int n,int c)3051 int YM2612TimerOver(int n,int c)
3052 {
3053 	YM2612 *F2612 = &(FM2612[n]);
3054 
3055 	if( c )
3056 	{	/* Timer B */
3057 		TimerBOver( &(F2612->OPN.ST) );
3058 	}
3059 	else
3060 	{	/* Timer A */
3061 		YM2612UpdateReq(n);
3062 		/* timer update */
3063 		TimerAOver( &(F2612->OPN.ST) );
3064 		/* CSM mode key,TL controll */
3065 		if( F2612->OPN.ST.mode & 0x80 )
3066 		{	/* CSM mode total level latch and auto key on */
3067 			CSMKeyControll( &(F2612->CH[2]) );
3068 		}
3069 	}
3070 	return F2612->OPN.ST.irq;
3071 }
3072 
3073 #endif /* BUILD_YM2612 */
3074 
3075 
3076 #if BUILD_YM2151
3077 /*******************************************************************************/
3078 /*		YM2151 local section                                                   */
3079 /*******************************************************************************/
3080 /* -------------------------- OPM ---------------------------------- */
3081 #undef  FM_SEG_SUPPORT
3082 #define FM_SEG_SUPPORT 0	/* OPM has not SEG type envelope */
3083 
3084 /* here's the virtual YM2151(OPM)  */
3085 typedef struct ym2151_f {
3086 	FM_ST ST;					/* general state     */
3087 	FM_CH CH[8];				/* channel state     */
3088 	UINT8 ct;					/* CT0,1             */
3089 	UINT32 NoiseCnt;			/* noise generator   */
3090 	UINT32 NoiseIncr;			/* noise mode enable & step */
3091 #if FM_LFO_SUPPORT
3092 	/* LFO */
3093 	UINT32 LFOCnt;
3094 	UINT32 LFOIncr;
3095 	UINT8 pmd;					/* LFO pmd level     */
3096 	UINT8 amd;					/* LFO amd level     */
3097 	INT32 *wavetype;			/* LFO waveform      */
3098 	UINT8 testreg;				/* test register (LFO reset) */
3099 #endif
3100 	UINT32 KC_TABLE[8*12*64+950];/* keycode,keyfunction -> count */
3101 	mem_write_handler PortWrite;/*  callback when write CT0/CT1 */
3102 } YM2151;
3103 
3104 static YM2151 *FMOPM=NULL;	/* array of YM2151's */
3105 static int YM2151NumChips;	/* total chip */
3106 
3107 #if FM_LFO_SUPPORT
3108 static INT32 OPM_LFO_waves[LFO_ENT*4];	/* LFO wave tabel    */
3109 static INT32 *OPM_LFO_wave;
3110 #endif
3111 
3112 /* current chip state */
3113 static UINT32 NoiseCnt , NoiseIncr;
3114 
3115 static INT32 *NOISE_TABLE[SIN_ENT];
3116 
3117 static const int DT2_TABLE[4]={ /* 4 DT2 values */
3118 /*
3119  *   DT2 defines offset in cents from base note
3120  *
3121  *   The table below defines offset in deltas table...
3122  *   User's Manual page 22
3123  *   Values below were calculated using formula:  value = orig.val * 1.5625
3124  *
3125  * DT2=0 DT2=1 DT2=2 DT2=3
3126  * 0     600   781   950
3127  */
3128 	0,    384,  500,  608
3129 };
3130 
3131 static const int KC_TO_SEMITONE[16]={
3132 	/*translate note code KC into more usable number of semitone*/
3133 	0*64, 1*64, 2*64, 3*64,
3134 	3*64, 4*64, 5*64, 6*64,
3135 	6*64, 7*64, 8*64, 9*64,
3136 	9*64,10*64,11*64,12*64
3137 };
3138 
3139 /* ---------- frequency counter  ---------- */
OPM_CALC_FCOUNT(YM2151 * OPM,FM_CH * CH)3140 static INLINE void OPM_CALC_FCOUNT(YM2151 *OPM , FM_CH *CH )
3141 {
3142 	if( CH->SLOT[SLOT1].Incr==-1)
3143 	{
3144 		int fc = CH->fc;
3145 		int kc = CH->kcode;
3146 
3147 		CALC_FCSLOT(&CH->SLOT[SLOT1] , OPM->KC_TABLE[fc + CH->SLOT[SLOT1].DT2] , kc );
3148 		CALC_FCSLOT(&CH->SLOT[SLOT2] , OPM->KC_TABLE[fc + CH->SLOT[SLOT2].DT2] , kc );
3149 		CALC_FCSLOT(&CH->SLOT[SLOT3] , OPM->KC_TABLE[fc + CH->SLOT[SLOT3].DT2] , kc );
3150 		CALC_FCSLOT(&CH->SLOT[SLOT4] , OPM->KC_TABLE[fc + CH->SLOT[SLOT4].DT2] , kc );
3151 	}
3152 }
3153 
3154 /* ---------- calcrate one of channel7 ---------- */
OPM_CALC_CH7(FM_CH * CH)3155 static INLINE void OPM_CALC_CH7( FM_CH *CH )
3156 {
3157 	UINT32 eg_out1,eg_out2,eg_out3,eg_out4;  //envelope output
3158 
3159 	/* Phase Generator */
3160 #if FM_LFO_SUPPORT
3161 	INT32 pms = lfo_pmd * CH->pms / LFO_RATE;
3162 	if(pms)
3163 	{
3164 		pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr + (INT32)(pms * CH->SLOT[SLOT1].Incr) / PMS_RATE);
3165 		pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr + (INT32)(pms * CH->SLOT[SLOT2].Incr) / PMS_RATE);
3166 		pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr + (INT32)(pms * CH->SLOT[SLOT3].Incr) / PMS_RATE);
3167 		pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr + (INT32)(pms * CH->SLOT[SLOT4].Incr) / PMS_RATE);
3168 	}
3169 	else
3170 #endif
3171 	{
3172 		pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr);
3173 		pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr);
3174 		pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr);
3175 		pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr);
3176 	}
3177 	/* Envelope Generator */
3178 	FM_CALC_EG(eg_out1,CH->SLOT[SLOT1]);
3179 	FM_CALC_EG(eg_out2,CH->SLOT[SLOT2]);
3180 	FM_CALC_EG(eg_out3,CH->SLOT[SLOT3]);
3181 	FM_CALC_EG(eg_out4,CH->SLOT[SLOT4]);
3182 
3183 	/* connection */
3184 	if( eg_out1 < EG_CUT_OFF )	/* SLOT 1 */
3185 	{
3186 		if( CH->FB ){
3187 			/* with self feed back */
3188 			pg_in1 += (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
3189 			CH->op1_out[1] = CH->op1_out[0];
3190 		}
3191 		CH->op1_out[0] = OP_OUT(pg_in1,eg_out1);
3192 		/* output slot1 */
3193 		if( !CH->connect1 )
3194 		{
3195 			/* algorythm 5  */
3196 			pg_in2 += CH->op1_out[0];
3197 			pg_in3 += CH->op1_out[0];
3198 			pg_in4 += CH->op1_out[0];
3199 		}else{
3200 			/* other algorythm */
3201 			*CH->connect1 += CH->op1_out[0];
3202 		}
3203 	}
3204 	if( eg_out2 < EG_CUT_OFF )	/* SLOT 2 */
3205 		*CH->connect2 += OP_OUT(pg_in2,eg_out2);
3206 	if( eg_out3 < EG_CUT_OFF )	/* SLOT 3 */
3207 		*CH->connect3 += OP_OUT(pg_in3,eg_out3);
3208 	/* SLOT 4 */
3209 	if(NoiseIncr)
3210 	{
3211 		NoiseCnt += NoiseIncr;
3212 		if( eg_out4 < EG_CUT_OFF )
3213 			*CH->connect4 += OP_OUTN(NoiseCnt,eg_out4);
3214 	}
3215 	else
3216 	{
3217 		if( eg_out4 < EG_CUT_OFF )
3218 			*CH->connect4 += OP_OUT(pg_in4,eg_out4);
3219 	}
3220 }
3221 
OPMInitTable(void)3222 static int OPMInitTable(void)
3223 {
3224 	int i;
3225 
3226 	/* NOISE wave table */
3227 	for(i=0;i<SIN_ENT;i++)
3228 	{
3229 		int sign = rand()&1 ? TL_MAX : 0;
3230 		int lev = rand()&0x1ff;
3231 		//pom = lev ? 20*log10(0x200/lev) : 0;   /* decibel */
3232 		//NOISE_TABLE[i] = &TL_TABLE[sign + (int)(pom / EG_STEP)]; /* TL_TABLE steps */
3233 		NOISE_TABLE[i] = &TL_TABLE[sign + lev * EG_ENT/0x200]; /* TL_TABLE steps */
3234 	}
3235 
3236 #if FM_LFO_SUPPORT
3237 	/* LFO wave tables , 4 pattern */
3238 	for(i=0;i<LFO_ENT;i++)
3239 	{
3240 		OPM_LFO_waves[          i]= LFO_RATE * i / LFO_ENT /127;
3241 		OPM_LFO_waves[LFO_ENT  +i]= ( i<LFO_ENT/2 ? 0 : LFO_RATE )/127;
3242 		OPM_LFO_waves[LFO_ENT*2+i]= LFO_RATE* (i<LFO_ENT/2 ? i : LFO_ENT-i) /(LFO_ENT/2) /127;
3243 		OPM_LFO_waves[LFO_ENT*3+i]= LFO_RATE * (rand()&0xff) /256 /127;
3244 	}
3245 #endif
3246 	return FMInitTable();
3247 }
3248 
3249 /* ---------- priscaler set(and make time tables) ---------- */
OPMResetTable(int num)3250 static void OPMResetTable( int num )
3251 {
3252     YM2151 *OPM = &(FMOPM[num]);
3253 	int i;
3254 	float pom;
3255 	float rate;
3256 
3257 	if (FMOPM[num].ST.rate)
3258 	{
3259 #ifndef MAME_FASTSOUND
3260 		rate = (float)(1<<FREQ_BITS) / (3579545.0 / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
3261 #else
3262 	    if (fast_sound)
3263     		rate = (float)(1<<FREQ_BITS) / ((3579545.0/2.0) / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
3264         else
3265 	    	rate = (float)(1<<FREQ_BITS) / (3579545.0 / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
3266 #endif
3267 	}
3268 	else rate = 1;
3269 
3270 	for (i=0; i<8*12*64+950; i++)
3271 	{
3272 		/* This calculation type was used from the Jarek's YM2151 emulator */
3273 		pom = 6.875 * pow (2, ((i+4*64)*1.5625/1200.0) ); /*13.75Hz is note A 12semitones below A-0, so D#0 is 4 semitones above then*/
3274 		/*calculate phase increment for above precounted Hertz value*/
3275 		OPM->KC_TABLE[i] = (UINT32)(pom * rate);
3276 		/*LOG(LOG_WAR,("OPM KC %d = %x\n",i,OPM->KC_TABLE[i]));*/
3277 	}
3278 
3279 	/* make time tables */
3280 	init_timetables( &OPM->ST , OPM_DTTABLE , OPM_ARRATE , OPM_DRRATE );
3281 
3282 }
3283 
3284 /* ---------- write a register on YM2151 chip number 'n' ---------- */
OPMWriteReg(int n,int r,int v)3285 static void OPMWriteReg(int n, int r, int v)
3286 {
3287 	UINT8 c;
3288 	FM_CH *CH;
3289 	FM_SLOT *SLOT;
3290 
3291     YM2151 *OPM = &(FMOPM[n]);
3292 
3293 	c   = OPM_CHAN(r);
3294 	CH  = &OPM->CH[c];
3295 	SLOT= &CH->SLOT[OPM_SLOT(r)];
3296 
3297 	switch( r & 0xe0 ){
3298 	case 0x00: /* 0x00-0x1f */
3299 		switch( r ){
3300 #if FM_LFO_SUPPORT
3301 		case 0x01:	/* test */
3302 			if( (OPM->testreg&(OPM->testreg^v))&0x02 ) /* fall eggge */
3303 			{	/* reset LFO counter */
3304 				OPM->LFOCnt = 0;
3305 				cur_chip = NULL;
3306 			}
3307 			OPM->testreg = v;
3308 			break;
3309 #endif
3310 		case 0x08:	/* key on / off */
3311 			c = v&7;
3312 			/* CSM mode */
3313 			if( OPM->ST.mode & 0x80 ) break;
3314 			CH = &OPM->CH[c];
3315 			if(v&0x08) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
3316 			if(v&0x10) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
3317 			if(v&0x20) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
3318 			if(v&0x40) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
3319 			break;
3320 		case 0x0f:	/* Noise freq (ch7.op4) */
3321 			/* b7 = Noise enable */
3322 			/* b0-4 noise freq  */
3323 			OPM->NoiseIncr = !(v&0x80) ? 0 :
3324 				/* !!!!! unknown noise freqency rate !!!!! */
3325 				(UINT32)((1<<FREQ_BITS) / 65536 * (v&0x1f) * OPM->ST.freqbase);
3326 			cur_chip = NULL;
3327 #if 1
3328 			if( v & 0x80 ){
3329 				LOG(LOG_WAR,("OPM Noise mode selelted\n"));
3330 			}
3331 #endif
3332 			break;
3333 		case 0x10:	/* timer A High 8*/
3334 			OPM->ST.TA = (OPM->ST.TA & 0x03)|(((int)v)<<2);
3335 			break;
3336 		case 0x11:	/* timer A Low 2*/
3337 			OPM->ST.TA = (OPM->ST.TA & 0x3fc)|(v&3);
3338 			break;
3339 		case 0x12:	/* timer B */
3340 			OPM->ST.TB = v;
3341 			break;
3342 		case 0x14:	/* mode , timer controll */
3343 			FMSetMode( &(OPM->ST),n,v );
3344 			break;
3345 #if FM_LFO_SUPPORT
3346 		case 0x18:	/* lfreq   */
3347 			/* f = fm * 2^(LFRQ/16) / (4295*10^6) */
3348 			{
3349 				static float drate[16]={
3350 					1.0        ,1.044273782,1.090507733,1.138788635, //0-3
3351 					1.189207115,1.241857812,1.296839555,1.354255547, //4-7
3352 					1.414213562,1.476826146,1.542210825,1.610490332, //8-11
3353 					1.681792831,1.75625216 ,1.834008086,1.915206561};
3354 				float rate = pow(2.0,v/16)*drate[v&0x0f] / 4295000000.0;
3355 				OPM->LFOIncr = (UINT32)((float)LFO_ENT*(1<<LFO_SHIFT) * (OPM->ST.freqbase*64) * rate);
3356 				cur_chip = NULL;
3357 			}
3358 			break;
3359 		case 0x19:	/* PMD/AMD */
3360 			if( v & 0x80 ) OPM->pmd = v & 0x7f;
3361 			else           OPM->amd = v & 0x7f;
3362 			break;
3363 #endif
3364 		case 0x1b:	/* CT , W  */
3365 			/* b7 = CT1 */
3366 			/* b6 = CT0 */
3367 			/* b0-2 = wave form(LFO) 0=nokogiri,1=houkei,2=sankaku,3=noise */
3368 			//if(OPM->ct != v)
3369 			{
3370 				OPM->ct = v>>6;
3371 				if( OPM->PortWrite != 0)
3372 					OPM->PortWrite(0, OPM->ct ); /* bit0 = CT0,bit1 = CT1 */
3373 			}
3374 #if FM_LFO_SUPPORT
3375 			if( OPM->wavetype != &OPM_LFO_waves[(v&3)*LFO_ENT])
3376 			{
3377 				OPM->wavetype = &OPM_LFO_waves[(v&3)*LFO_ENT];
3378 				cur_chip = NULL;
3379 			}
3380 #endif
3381 			break;
3382 		}
3383 		break;
3384 	case 0x20:	/* 20-3f */
3385 		switch( OPM_SLOT(r) ){
3386 		case 0: /* 0x20-0x27 : RL,FB,CON */
3387 			{
3388 				int feedback = (v>>3)&7;
3389 				CH->ALGO = v&7;
3390 				CH->FB  = feedback ? 8+1 - feedback : 0;
3391 				/* RL order -> LR order */
3392 				CH->PAN = ((v>>7)&1) | ((v>>5)&2);
3393 				setup_connection( CH );
3394 			}
3395 			break;
3396 		case 1: /* 0x28-0x2f : Keycode */
3397 			{
3398 				int blk = (v>>4)&7;
3399 				/* make keyscale code */
3400 				CH->kcode = (v>>2)&0x1f;
3401 				/* make basic increment counter 22bit = 1 cycle */
3402 				CH->fc = (blk * (12*64)) + KC_TO_SEMITONE[v&0x0f] + CH->fn_h;
3403 				CH->SLOT[SLOT1].Incr=-1;
3404 			}
3405 			break;
3406 		case 2: /* 0x30-0x37 : Keyfunction */
3407 			CH->fc -= CH->fn_h;
3408 			CH->fn_h = v>>2;
3409 			CH->fc += CH->fn_h;
3410 			CH->SLOT[SLOT1].Incr=-1;
3411 			break;
3412 #if FM_LFO_SUPPORT
3413 		case 3: /* 0x38-0x3f : PMS / AMS */
3414 			/* b0-1 AMS */
3415 			/* AMS * 23.90625db @ AMD=127 */
3416 			//CH->ams = (v & 0x03) * (23.90625/EG_STEP);
3417 			CH->ams = (UINT32)( (23.90625/EG_STEP) / (1<<(3-(v&3))) );
3418 			CH->SLOT[SLOT1].ams = CH->ams * CH->SLOT[SLOT1].amon;
3419 			CH->SLOT[SLOT2].ams = CH->ams * CH->SLOT[SLOT2].amon;
3420 			CH->SLOT[SLOT3].ams = CH->ams * CH->SLOT[SLOT3].amon;
3421 			CH->SLOT[SLOT4].ams = CH->ams * CH->SLOT[SLOT4].amon;
3422 			/* b4-6 PMS */
3423 			/* 0,5,10,20,50,100,400,700 (cent) @ PMD=127 */
3424 			{
3425 				/* 1 octabe = 1200cent = +100%/-50% */
3426 				/* 100cent  = 1seminote = 6% ?? */
3427 				static const int pmd_table[8] = {0,5,10,20,50,100,400,700};
3428 				CH->pms = (INT32)( (1.5/1200.0)*pmd_table[(v>>4) & 0x07] * PMS_RATE );
3429 			}
3430 			break;
3431 #endif
3432 		}
3433 		break;
3434 	case 0x40:	/* DT1,MUL */
3435 		set_det_mul(&OPM->ST,CH,SLOT,v);
3436 		break;
3437 	case 0x60:	/* TL */
3438 		set_tl(CH,SLOT,v,(OPM->ST.mode & 0x80) );
3439 		break;
3440 	case 0x80:	/* KS, AR */
3441 		set_ar_ksr(CH,SLOT,v,OPM->ST.AR_TABLE);
3442 		break;
3443 	case 0xa0:	/* AMS EN,D1R */
3444 		set_dr(SLOT,v,OPM->ST.DR_TABLE);
3445 #if FM_LFO_SUPPORT
3446 		/* bit7 = AMS ENABLE */
3447 		SLOT->amon = v>>7;
3448 		SLOT->ams = CH->ams * SLOT->amon;
3449 #endif
3450 		break;
3451 	case 0xc0:	/* DT2 ,D2R */
3452 		SLOT->DT2  = DT2_TABLE[v>>6];
3453 		CH->SLOT[SLOT1].Incr=-1;
3454 		set_sr(SLOT,v,OPM->ST.DR_TABLE);
3455 		break;
3456 	case 0xe0:	/* D1L, RR */
3457 		set_sl_rr(SLOT,v,OPM->ST.DR_TABLE);
3458 		break;
3459     }
3460 }
3461 
YM2151Write(int n,int a,UINT8 v)3462 int YM2151Write(int n,int a,UINT8 v)
3463 {
3464 	YM2151 *F2151 = &(FMOPM[n]);
3465 
3466 	if( !(a&1) )
3467 	{	/* address port */
3468 		F2151->ST.address = v & 0xff;
3469 	}
3470 	else
3471 	{	/* data port */
3472 		int addr = F2151->ST.address;
3473 #ifndef MAME_FASTSOUND
3474 		YM2151UpdateReq(n);
3475 #else
3476 		if (!fast_sound) YM2151UpdateReq(n);
3477 #endif
3478 		/* write register */
3479 		 OPMWriteReg(n,addr,v);
3480 	}
3481 	return F2151->ST.irq;
3482 }
3483 
3484 /* ---------- reset one of chip ---------- */
OPMResetChip(int num)3485 void OPMResetChip(int num)
3486 {
3487 	int i;
3488     YM2151 *OPM = &(FMOPM[num]);
3489 
3490 	OPMResetTable( num );
3491 	reset_channel( &OPM->ST , &OPM->CH[0] , 8 );
3492 	/* status clear */
3493 	FM_IRQMASK_SET(&OPM->ST,0x03);
3494 	OPMWriteReg(num,0x1b,0x00);
3495 	/* reset OPerator paramater */
3496 	for(i = 0xff ; i >= 0x20 ; i-- ) OPMWriteReg(num,i,0);
3497 }
3498 
3499 /* ----------  Initialize YM2151 emulator(s) ----------    */
3500 /* 'num' is the number of virtual YM2151's to allocate     */
3501 /* 'rate' is sampling rate and 'bufsiz' is the size of the */
3502 /* buffer that should be updated at each interval          */
OPMInit(int num,int clock,int rate,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)3503 int OPMInit(int num, int clock, int rate,
3504                FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
3505 {
3506     int i;
3507 
3508     if (FMOPM) return (-1);	/* duplicate init. */
3509     cur_chip = NULL;	/* hiro-shi!! */
3510 
3511 	YM2151NumChips = num;
3512 
3513 	/* allocate ym2151 state space */
3514 	if( (FMOPM = (YM2151 *)malloc(sizeof(YM2151) * YM2151NumChips))==NULL)
3515 		return (-1);
3516 
3517 	/* clear */
3518 	memset(FMOPM,0,sizeof(YM2151) * YM2151NumChips);
3519 
3520 	/* allocate total lebel table (128kb space) */
3521 	if( !OPMInitTable() )
3522 	{
3523 		free( FMOPM );
3524 		return (-1);
3525 	}
3526 	for ( i = 0 ; i < YM2151NumChips; i++ ) {
3527 		FMOPM[i].ST.index = i;
3528 		FMOPM[i].ST.clock = clock;
3529 		FMOPM[i].ST.rate = rate;
3530 		/* FMOPM[i].ST.irq  = 0; */
3531 		/* FMOPM[i].ST.status = 0; */
3532 		FMOPM[i].ST.timermodel = FM_TIMER_INTERVAL;
3533 		FMOPM[i].ST.freqbase  = rate ? ((float)clock / rate) / 64 : 0;
3534 		FMOPM[i].ST.TimerBase = (float)TIME_ONE_SEC/((float)clock / 64.0);
3535 		/* Extend handler */
3536 		FMOPM[i].ST.Timer_Handler = TimerHandler;
3537 		FMOPM[i].ST.IRQ_Handler   = IRQHandler;
3538 		/* Reset callback handler of CT0/1 */
3539 		FMOPM[i].PortWrite = 0;
3540 		OPMResetChip(i);
3541 	}
3542 	return(0);
3543 }
3544 
3545 /* ---------- shut down emurator ----------- */
OPMShutdown()3546 void OPMShutdown()
3547 {
3548     if (!FMOPM) return;
3549 
3550 	FMCloseTable();
3551 	free(FMOPM);
3552 	FMOPM = NULL;
3553 }
3554 
YM2151Read(int n,int a)3555 UINT8 YM2151Read(int n,int a)
3556 {
3557 	if( !(a&1) ) return 0;
3558 	else         return FMOPM[n].ST.status;
3559 }
3560 
3561 /* ---------- make digital sound data ---------- */
OPMUpdateOne(int num,INT16 ** buffer,int length)3562 void OPMUpdateOne(int num, INT16 **buffer, int length)
3563 {
3564 	YM2151 *OPM = &(FMOPM[num]);
3565 	int amd,pmd;
3566 	FM_CH *ch;
3567 	FMSAMPLE  *bufL,*bufR;
3568 
3569 	/* set bufer */
3570 	bufL = buffer[0];
3571 	bufR = buffer[1];
3572 
3573 	if( (void *)OPM != cur_chip ){
3574 		cur_chip = (void *)OPM;
3575 
3576 		State = &OPM->ST;
3577 		/* channel pointer */
3578 		cch[0] = &OPM->CH[0];
3579 		cch[1] = &OPM->CH[1];
3580 		cch[2] = &OPM->CH[2];
3581 		cch[3] = &OPM->CH[3];
3582 		cch[4] = &OPM->CH[4];
3583 		cch[5] = &OPM->CH[5];
3584 		cch[6] = &OPM->CH[6];
3585 		cch[7] = &OPM->CH[7];
3586 		/* ch7.op4 noise mode / step */
3587 		NoiseIncr = OPM->NoiseIncr;
3588 		NoiseCnt  = OPM->NoiseCnt;
3589 #if FM_LFO_SUPPORT
3590 		/* LFO */
3591 		LFOCnt  = OPM->LFOCnt;
3592 		//LFOIncr = OPM->LFOIncr;
3593 		if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
3594 		OPM_LFO_wave = OPM->wavetype;
3595 #endif
3596 	}
3597 	amd = OPM->amd;
3598 	pmd = OPM->pmd;
3599 	if(amd==0 && pmd==0)
3600 		LFOIncr = 0;
3601 	else
3602 		LFOIncr = OPM->LFOIncr;
3603 
3604 	OPM_CALC_FCOUNT( OPM , cch[0] );
3605 	OPM_CALC_FCOUNT( OPM , cch[1] );
3606 	OPM_CALC_FCOUNT( OPM , cch[2] );
3607 	OPM_CALC_FCOUNT( OPM , cch[3] );
3608 	OPM_CALC_FCOUNT( OPM , cch[4] );
3609 	OPM_CALC_FCOUNT( OPM , cch[5] );
3610 	OPM_CALC_FCOUNT( OPM , cch[6] );
3611 	OPM_CALC_FCOUNT( OPM , cch[7] );
3612 
3613 	do
3614 	{
3615 #if FM_LFO_SUPPORT
3616 		/* LFO */
3617 		if( LFOIncr )
3618 		{
3619 			INT32 depth = OPM_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
3620 			lfo_amd = depth * amd;
3621 			lfo_pmd = (depth-(LFO_RATE/127/2)) * pmd;
3622 		}
3623 #endif
3624 		/* clear output acc. */
3625 		out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
3626 		/* calcrate channel output */
3627 		for(ch = cch[0] ; ch <= cch[6] ; ch++)
3628 			FM_CALC_CH( ch );
3629 		OPM_CALC_CH7( cch[7] );
3630 		/* buffering */
3631 		FM_BUFFERING_STEREO;
3632 		/* timer A controll */
3633 		INTERNAL_TIMER_A( State , cch[7] )
3634     }
3635     while (--length);
3636 	INTERNAL_TIMER_B(State,length)
3637 	OPM->NoiseCnt = NoiseCnt;
3638 #if FM_LFO_SUPPORT
3639 	OPM->LFOCnt = LFOCnt;
3640 #endif
3641 }
3642 
OPMSetPortHander(int n,mem_write_handler PortWrite)3643 void OPMSetPortHander(int n,mem_write_handler PortWrite)
3644 {
3645 	FMOPM[n].PortWrite = PortWrite;
3646 }
3647 
YM2151TimerOver(int n,int c)3648 int YM2151TimerOver(int n,int c)
3649 {
3650 	YM2151 *F2151 = &(FMOPM[n]);
3651 
3652 	if( c )
3653 	{	/* Timer B */
3654 		TimerBOver( &(F2151->ST) );
3655 	}
3656 	else
3657 	{	/* Timer A */
3658 		YM2151UpdateReq(n);
3659 		/* timer update */
3660 		TimerAOver( &(F2151->ST) );
3661 		/* CSM mode key,TL controll */
3662 		if( F2151->ST.mode & 0x80 )
3663 		{	/* CSM mode total level latch and auto key on */
3664 			CSMKeyControll( &(F2151->CH[0]) );
3665 			CSMKeyControll( &(F2151->CH[1]) );
3666 			CSMKeyControll( &(F2151->CH[2]) );
3667 			CSMKeyControll( &(F2151->CH[3]) );
3668 			CSMKeyControll( &(F2151->CH[4]) );
3669 			CSMKeyControll( &(F2151->CH[5]) );
3670 			CSMKeyControll( &(F2151->CH[6]) );
3671 			CSMKeyControll( &(F2151->CH[7]) );
3672 		}
3673 	}
3674 	return F2151->ST.irq;
3675 }
3676 
3677 #endif /* BUILD_YM2151 */
3678