1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * LGPL licensed version of MAMEs fmopl (V0.37a modified) by
22  * Tatsuyuki Satoh. Included from LGPL'ed AdPlug.
23  *
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <math.h>
31 
32 #include "mame.h"
33 
34 #include "audio/mixer.h"
35 #include "common/system.h"
36 #include "common/textconsole.h"
37 #include "common/util.h"
38 
39 #if defined(_WIN32_WCE) || defined(__SYMBIAN32__) || defined(__GP32__) || defined(GP2X) || defined(__MAEMO__) || defined(__DS__) || defined(__MINT__) || defined(__N64__)
40 #include "common/config-manager.h"
41 #endif
42 
43 #if defined(__DS__)
44 #include "dsmain.h"
45 #endif
46 
47 namespace OPL {
48 namespace MAME {
49 
~OPL()50 OPL::~OPL() {
51 	stop();
52 	MAME::OPLDestroy(_opl);
53 	_opl = 0;
54 }
55 
init()56 bool OPL::init() {
57 	if (_opl) {
58 		stopCallbacks();
59 		MAME::OPLDestroy(_opl);
60 	}
61 
62 	_opl = MAME::makeAdLibOPL(g_system->getMixer()->getOutputRate());
63 
64 	return (_opl != 0);
65 }
66 
reset()67 void OPL::reset() {
68 	MAME::OPLResetChip(_opl);
69 }
70 
write(int a,int v)71 void OPL::write(int a, int v) {
72 	MAME::OPLWrite(_opl, a, v);
73 }
74 
read(int a)75 byte OPL::read(int a) {
76 	return MAME::OPLRead(_opl, a);
77 }
78 
writeReg(int r,int v)79 void OPL::writeReg(int r, int v) {
80 	MAME::OPLWriteReg(_opl, r, v);
81 }
82 
generateSamples(int16 * buffer,int length)83 void OPL::generateSamples(int16 *buffer, int length) {
84 	MAME::YM3812UpdateOne(_opl, buffer, length);
85 }
86 
87 /* -------------------- preliminary define section --------------------- */
88 /* attack/decay rate time rate */
89 #define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
90 #define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
91 
92 #define FREQ_BITS 24			/* frequency turn          */
93 
94 /* counter bits = 20 , octerve 7 */
95 #define FREQ_RATE   (1<<(FREQ_BITS-20))
96 #define TL_BITS    (FREQ_BITS+2)
97 
98 /* final output shift , limit minimum and maximum */
99 #define OPL_OUTSB   (TL_BITS+3-16)		/* OPL output final shift 16bit */
100 #define OPL_MAXOUT   (0x7fff<<OPL_OUTSB)
101 #define OPL_MINOUT (-(0x8000<<OPL_OUTSB))
102 
103 /* -------------------- quality selection --------------------- */
104 
105 /* sinwave entries */
106 /* used static memory = SIN_ENT * 4 (byte) */
107 #ifdef __DS__
108 #define SIN_ENT_SHIFT 8
109 #else
110 #define SIN_ENT_SHIFT 11
111 #endif
112 #define SIN_ENT (1<<SIN_ENT_SHIFT)
113 
114 /* output level entries (envelope,sinwave) */
115 /* envelope counter lower bits */
116 int ENV_BITS;
117 /* envelope output entries */
118 int EG_ENT;
119 
120 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
121 /* used static  memory = EG_ENT*4 (byte)                     */
122 int EG_OFF;								 /* OFF */
123 int EG_DED;
124 int EG_DST;								 /* DECAY START */
125 int EG_AED;
126 #define EG_AST   0                       /* ATTACK START */
127 
128 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
129 
130 /* LFO table entries */
131 #define VIB_ENT 512
132 #define VIB_SHIFT (32-9)
133 #define AMS_ENT 512
134 #define AMS_SHIFT (32-9)
135 
136 #define VIB_RATE_SHIFT 8
137 #define VIB_RATE (1<<VIB_RATE_SHIFT)
138 
139 /* -------------------- local defines , macros --------------------- */
140 
141 /* register number to channel number , slot offset */
142 #define SLOT1 0
143 #define SLOT2 1
144 
145 /* envelope phase */
146 #define ENV_MOD_RR  0x00
147 #define ENV_MOD_DR  0x01
148 #define ENV_MOD_AR  0x02
149 
150 /* -------------------- tables --------------------- */
151 static const int slot_array[32] = {
152 	 0, 2, 4, 1, 3, 5,-1,-1,
153 	 6, 8,10, 7, 9,11,-1,-1,
154 	12,14,16,13,15,17,-1,-1,
155 	-1,-1,-1,-1,-1,-1,-1,-1
156 };
157 
158 static uint KSL_TABLE[8 * 16];
159 
160 static const double KSL_TABLE_SEED[8 * 16] = {
161 	/* OCT 0 */
162 	0.000, 0.000, 0.000, 0.000,
163 	0.000, 0.000, 0.000, 0.000,
164 	0.000, 0.000, 0.000, 0.000,
165 	0.000, 0.000, 0.000, 0.000,
166 	/* OCT 1 */
167 	0.000, 0.000, 0.000, 0.000,
168 	0.000, 0.000, 0.000, 0.000,
169 	0.000, 0.750, 1.125, 1.500,
170 	1.875, 2.250, 2.625, 3.000,
171 	/* OCT 2 */
172 	0.000, 0.000, 0.000, 0.000,
173 	0.000, 1.125, 1.875, 2.625,
174 	3.000, 3.750, 4.125, 4.500,
175 	4.875, 5.250, 5.625, 6.000,
176 	/* OCT 3 */
177 	0.000, 0.000, 0.000, 1.875,
178 	3.000, 4.125, 4.875, 5.625,
179 	6.000, 6.750, 7.125, 7.500,
180 	7.875, 8.250, 8.625, 9.000,
181 	/* OCT 4 */
182 	0.000, 0.000, 3.000, 4.875,
183 	6.000, 7.125, 7.875, 8.625,
184 	9.000, 9.750, 10.125, 10.500,
185 	10.875, 11.250, 11.625, 12.000,
186 	/* OCT 5 */
187 	0.000, 3.000, 6.000, 7.875,
188 	9.000, 10.125, 10.875, 11.625,
189 	12.000, 12.750, 13.125, 13.500,
190 	13.875, 14.250, 14.625, 15.000,
191 	/* OCT 6 */
192 	0.000, 6.000, 9.000, 10.875,
193 	12.000, 13.125, 13.875, 14.625,
194 	15.000, 15.750, 16.125, 16.500,
195 	16.875, 17.250, 17.625, 18.000,
196 	/* OCT 7 */
197 	0.000, 9.000, 12.000, 13.875,
198 	15.000, 16.125, 16.875, 17.625,
199 	18.000, 18.750, 19.125, 19.500,
200 	19.875, 20.250, 20.625, 21.000
201 };
202 
203 /* sustain level table (3db per step) */
204 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
205 
206 static int SL_TABLE[16];
207 
208 static const uint SL_TABLE_SEED[16] = {
209 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31
210 };
211 
212 #define TL_MAX (EG_ENT * 2) /* limit(tl + ksr + envelope) + sinwave */
213 /* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
214 /* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
215 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
216 static int *TL_TABLE;
217 
218 /* pointers to TL_TABLE with sinwave output offset */
219 static int **SIN_TABLE;
220 
221 /* LFO table */
222 static int *AMS_TABLE;
223 static int *VIB_TABLE;
224 
225 /* envelope output curve table */
226 /* attack + decay + OFF */
227 //static int ENV_CURVE[2*EG_ENT+1];
228 //static int ENV_CURVE[2 * 4096 + 1];   // to keep it static ...
229 static int *ENV_CURVE;
230 
231 
232 /* multiple table */
233 #define ML(a) (uint)(a * 2)
234 static const uint MUL_TABLE[16]= {
235 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
236 	ML(0.50), ML(1.00), ML(2.00),  ML(3.00), ML(4.00), ML(5.00), ML(6.00), ML(7.00),
237 	ML(8.00), ML(9.00), ML(10.00), ML(10.00),ML(12.00),ML(12.00),ML(15.00),ML(15.00)
238 };
239 #undef ML
240 
241 /* dummy attack / decay rate ( when rate == 0 ) */
242 static int RATE_0[16]=
243 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
244 
245 /* -------------------- static state --------------------- */
246 
247 /* lock level of common table */
248 static int num_lock = 0;
249 
250 /* work table */
251 static void *cur_chip = NULL;	/* current chip point */
252 /* currenct chip state */
253 /* static OPLSAMPLE  *bufL,*bufR; */
254 static OPL_CH *S_CH;
255 static OPL_CH *E_CH;
256 OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
257 
258 static int outd[1];
259 static int ams;
260 static int vib;
261 int *ams_table;
262 int *vib_table;
263 static int amsIncr;
264 static int vibIncr;
265 static int feedback2;		/* connect for SLOT 2 */
266 
267 /* --------------------- rebuild tables ------------------- */
268 
269 #define SC_KSL(mydb) ((uint) (mydb / (EG_STEP / 2)))
270 #define SC_SL(db) (int)(db * ((3 / EG_STEP) * (1 << ENV_BITS))) + EG_DST
271 
OPLBuildTables(int ENV_BITS_PARAM,int EG_ENT_PARAM)272 void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) {
273 	int i;
274 
275 	ENV_BITS = ENV_BITS_PARAM;
276 	EG_ENT = EG_ENT_PARAM;
277 	EG_OFF = ((2 * EG_ENT)<<ENV_BITS);  /* OFF          */
278 	EG_DED = EG_OFF;
279 	EG_DST = (EG_ENT << ENV_BITS);     /* DECAY  START */
280 	EG_AED = EG_DST;
281 	//EG_STEP = (96.0/EG_ENT);
282 
283 	for (i = 0; i < ARRAYSIZE(KSL_TABLE_SEED); i++)
284 		KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]);
285 
286 	for (i = 0; i < ARRAYSIZE(SL_TABLE_SEED); i++)
287 		SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]);
288 }
289 
290 #undef SC_KSL
291 #undef SC_SL
292 
293 /* --------------------- subroutines  --------------------- */
294 
295 /* status set and IRQ handling */
OPL_STATUS_SET(FM_OPL * OPL,int flag)296 inline void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
297 	/* set status flag */
298 	OPL->status |= flag;
299 	if (!(OPL->status & 0x80)) {
300 		if (OPL->status & OPL->statusmask) {	/* IRQ on */
301 			OPL->status |= 0x80;
302 			/* callback user interrupt handler (IRQ is OFF to ON) */
303 			if (OPL->IRQHandler)
304 				(OPL->IRQHandler)(OPL->IRQParam,1);
305 		}
306 	}
307 }
308 
309 /* status reset and IRQ handling */
OPL_STATUS_RESET(FM_OPL * OPL,int flag)310 inline void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
311 	/* reset status flag */
312 	OPL->status &= ~flag;
313 	if ((OPL->status & 0x80)) {
314 		if (!(OPL->status & OPL->statusmask)) {
315 			OPL->status &= 0x7f;
316 			/* callback user interrupt handler (IRQ is ON to OFF) */
317 			if (OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
318 		}
319 	}
320 }
321 
322 /* IRQ mask set */
OPL_STATUSMASK_SET(FM_OPL * OPL,int flag)323 inline void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
324 	OPL->statusmask = flag;
325 	/* IRQ handling check */
326 	OPL_STATUS_SET(OPL,0);
327 	OPL_STATUS_RESET(OPL,0);
328 }
329 
330 /* ----- key on  ----- */
OPL_KEYON(OPL_SLOT * SLOT)331 inline void OPL_KEYON(OPL_SLOT *SLOT) {
332 	/* sin wave restart */
333 	SLOT->Cnt = 0;
334 	/* set attack */
335 	SLOT->evm = ENV_MOD_AR;
336 	SLOT->evs = SLOT->evsa;
337 	SLOT->evc = EG_AST;
338 	SLOT->eve = EG_AED;
339 }
340 
341 /* ----- key off ----- */
OPL_KEYOFF(OPL_SLOT * SLOT)342 inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
343 	if (SLOT->evm > ENV_MOD_RR) {
344 		/* set envelope counter from envleope output */
345 
346 		// WORKAROUND: The Kyra engine does something very strange when
347 		// starting a new song. For each channel:
348 		//
349 		// * The release rate is set to "fastest".
350 		// * Any note is keyed off.
351 		// * A very low-frequency note is keyed on.
352 		//
353 		// Usually, what happens next is that the real notes is keyed
354 		// on immediately, in which case there's no problem.
355 		//
356 		// However, if the note is again keyed off (because the channel
357 		// begins on a rest rather than a note), the envelope counter
358 		// was moved from the very lowest point on the attack curve to
359 		// the very highest point on the release curve.
360 		//
361 		// Again, this might not be a problem, if the release rate is
362 		// still set to "fastest". But in many cases, it had already
363 		// been increased. And, possibly because of inaccuracies in the
364 		// envelope generator, that would cause the note to "fade out"
365 		// for quite a long time.
366 		//
367 		// What we really need is a way to find the correct starting
368 		// point for the envelope counter, and that may be what the
369 		// commented-out line below is meant to do. For now, simply
370 		// handle the pathological case.
371 
372 		if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
373 			SLOT->evc = EG_DED;
374 		else if (!(SLOT->evc & EG_DST))
375 			//SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
376 			SLOT->evc = EG_DST;
377 		SLOT->eve = EG_DED;
378 		SLOT->evs = SLOT->evsr;
379 		SLOT->evm = ENV_MOD_RR;
380 	}
381 }
382 
383 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
384 
385 /* return : envelope output */
OPL_CALC_SLOT(OPL_SLOT * SLOT)386 inline uint OPL_CALC_SLOT(OPL_SLOT *SLOT) {
387 	/* calcrate envelope generator */
388 	if ((SLOT->evc += SLOT->evs) >= SLOT->eve) {
389 		switch (SLOT->evm) {
390 		case ENV_MOD_AR: /* ATTACK -> DECAY1 */
391 			/* next DR */
392 			SLOT->evm = ENV_MOD_DR;
393 			SLOT->evc = EG_DST;
394 			SLOT->eve = SLOT->SL;
395 			SLOT->evs = SLOT->evsd;
396 			break;
397 		case ENV_MOD_DR: /* DECAY -> SL or RR */
398 			SLOT->evc = SLOT->SL;
399 			SLOT->eve = EG_DED;
400 			if (SLOT->eg_typ) {
401 				SLOT->evs = 0;
402 			} else {
403 				SLOT->evm = ENV_MOD_RR;
404 				SLOT->evs = SLOT->evsr;
405 			}
406 			break;
407 		case ENV_MOD_RR: /* RR -> OFF */
408 			SLOT->evc = EG_OFF;
409 			SLOT->eve = EG_OFF + 1;
410 			SLOT->evs = 0;
411 			break;
412 		}
413 	}
414 	/* calcrate envelope */
415 	return SLOT->TLL + ENV_CURVE[SLOT->evc>>ENV_BITS] + (SLOT->ams ? ams : 0);
416 }
417 
418 /* set algorythm connection */
set_algorythm(OPL_CH * CH)419 static void set_algorythm(OPL_CH *CH) {
420 	int *carrier = &outd[0];
421 	CH->connect1 = CH->CON ? carrier : &feedback2;
422 	CH->connect2 = carrier;
423 }
424 
425 /* ---------- frequency counter for operater update ---------- */
CALC_FCSLOT(OPL_CH * CH,OPL_SLOT * SLOT)426 inline void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
427 	int ksr;
428 
429 	/* frequency step counter */
430 	SLOT->Incr = CH->fc * SLOT->mul;
431 	ksr = CH->kcode >> SLOT->KSR;
432 
433 	if (SLOT->ksr != ksr) {
434 		SLOT->ksr = ksr;
435 		/* attack , decay rate recalcration */
436 		SLOT->evsa = SLOT->AR[ksr];
437 		SLOT->evsd = SLOT->DR[ksr];
438 		SLOT->evsr = SLOT->RR[ksr];
439 	}
440 	SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
441 }
442 
443 /* set multi,am,vib,EG-TYP,KSR,mul */
set_mul(FM_OPL * OPL,int slot,int v)444 inline void set_mul(FM_OPL *OPL, int slot, int v) {
445 	OPL_CH   *CH   = &OPL->P_CH[slot>>1];
446 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
447 
448 	SLOT->mul    = MUL_TABLE[v & 0x0f];
449 	SLOT->KSR    = (v & 0x10) ? 0 : 2;
450 	SLOT->eg_typ = (v & 0x20) >> 5;
451 	SLOT->vib    = (v & 0x40);
452 	SLOT->ams    = (v & 0x80);
453 	CALC_FCSLOT(CH, SLOT);
454 }
455 
456 /* set ksl & tl */
set_ksl_tl(FM_OPL * OPL,int slot,int v)457 inline void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
458 	OPL_CH   *CH   = &OPL->P_CH[slot>>1];
459 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
460 	int ksl = v >> 6; /* 0 / 1.5 / 3 / 6 db/OCT */
461 
462 	SLOT->ksl = ksl ? 3-ksl : 31;
463 	SLOT->TL  = (int)((v & 0x3f) * (0.75 / EG_STEP)); /* 0.75db step */
464 
465 	if (!(OPL->mode & 0x80)) {	/* not CSM latch total level */
466 		SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
467 	}
468 }
469 
470 /* set attack rate & decay rate  */
set_ar_dr(FM_OPL * OPL,int slot,int v)471 inline void set_ar_dr(FM_OPL *OPL, int slot, int v) {
472 	OPL_CH   *CH   = &OPL->P_CH[slot>>1];
473 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
474 	int ar = v >> 4;
475 	int dr = v & 0x0f;
476 
477 	SLOT->AR = ar ? &OPL->AR_TABLE[ar << 2] : RATE_0;
478 	SLOT->evsa = SLOT->AR[SLOT->ksr];
479 	if (SLOT->evm == ENV_MOD_AR)
480 		SLOT->evs = SLOT->evsa;
481 
482 	SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
483 	SLOT->evsd = SLOT->DR[SLOT->ksr];
484 	if (SLOT->evm == ENV_MOD_DR)
485 		SLOT->evs = SLOT->evsd;
486 }
487 
488 /* set sustain level & release rate */
set_sl_rr(FM_OPL * OPL,int slot,int v)489 inline void set_sl_rr(FM_OPL *OPL, int slot, int v) {
490 	OPL_CH   *CH   = &OPL->P_CH[slot>>1];
491 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
492 	int sl = v >> 4;
493 	int rr = v & 0x0f;
494 
495 	SLOT->SL = SL_TABLE[sl];
496 	if (SLOT->evm == ENV_MOD_DR)
497 		SLOT->eve = SLOT->SL;
498 	SLOT->RR = &OPL->DR_TABLE[rr<<2];
499 	SLOT->evsr = SLOT->RR[SLOT->ksr];
500 	if (SLOT->evm == ENV_MOD_RR)
501 		SLOT->evs = SLOT->evsr;
502 }
503 
504 /* operator output calcrator */
505 
506 #define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt + con)>>(24-SIN_ENT_SHIFT)) & (SIN_ENT-1)][env]
507 /* ---------- calcrate one of channel ---------- */
OPL_CALC_CH(OPL_CH * CH)508 inline void OPL_CALC_CH(OPL_CH *CH) {
509 	uint env_out;
510 	OPL_SLOT *SLOT;
511 
512 	feedback2 = 0;
513 	/* SLOT 1 */
514 	SLOT = &CH->SLOT[SLOT1];
515 	env_out=OPL_CALC_SLOT(SLOT);
516 	if (env_out < (uint)(EG_ENT - 1)) {
517 		/* PG */
518 		if (SLOT->vib)
519 			SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
520 		else
521 			SLOT->Cnt += SLOT->Incr;
522 		/* connection */
523 		if (CH->FB) {
524 			int feedback1 = (CH->op1_out[0] + CH->op1_out[1]) >> CH->FB;
525 			CH->op1_out[1] = CH->op1_out[0];
526 			*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
527 		} else {
528 			*CH->connect1 += OP_OUT(SLOT, env_out, 0);
529 		}
530 	} else {
531 		CH->op1_out[1] = CH->op1_out[0];
532 		CH->op1_out[0] = 0;
533 	}
534 	/* SLOT 2 */
535 	SLOT = &CH->SLOT[SLOT2];
536 	env_out=OPL_CALC_SLOT(SLOT);
537 	if (env_out < (uint)(EG_ENT - 1)) {
538 		/* PG */
539 		if (SLOT->vib)
540 			SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
541 		else
542 			SLOT->Cnt += SLOT->Incr;
543 		/* connection */
544 		outd[0] += OP_OUT(SLOT, env_out, feedback2);
545 	}
546 }
547 
548 /* ---------- calcrate rythm block ---------- */
549 #define WHITE_NOISE_db 6.0
OPL_CALC_RH(FM_OPL * OPL,OPL_CH * CH)550 inline void OPL_CALC_RH(FM_OPL *OPL, OPL_CH *CH) {
551 	uint env_tam, env_sd, env_top, env_hh;
552 	// This code used to do int(OPL->rnd.getRandomBit() * (WHITE_NOISE_db / EG_STEP)),
553 	// but EG_STEP = 96.0/EG_ENT, and WHITE_NOISE_db=6.0. So, that's equivalent to
554 	// int(OPL->rnd.getRandomBit() * EG_ENT/16). We know that EG_ENT is 4096, or 1024,
555 	// or 128, so we can safely avoid any FP ops.
556 	int whitenoise = OPL->rnd->getRandomBit() * (EG_ENT>>4);
557 
558 	int tone8;
559 
560 	OPL_SLOT *SLOT;
561 	int env_out;
562 
563 	/* BD : same as FM serial mode and output level is large */
564 	feedback2 = 0;
565 	/* SLOT 1 */
566 	SLOT = &CH[6].SLOT[SLOT1];
567 	env_out = OPL_CALC_SLOT(SLOT);
568 	if (env_out < EG_ENT-1) {
569 		/* PG */
570 		if (SLOT->vib)
571 			SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
572 		else
573 			SLOT->Cnt += SLOT->Incr;
574 		/* connection */
575 		if (CH[6].FB) {
576 			int feedback1 = (CH[6].op1_out[0] + CH[6].op1_out[1]) >> CH[6].FB;
577 			CH[6].op1_out[1] = CH[6].op1_out[0];
578 			feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT, env_out, feedback1);
579 		}
580 		else {
581 			feedback2 = OP_OUT(SLOT, env_out, 0);
582 		}
583 	} else {
584 		feedback2 = 0;
585 		CH[6].op1_out[1] = CH[6].op1_out[0];
586 		CH[6].op1_out[0] = 0;
587 	}
588 	/* SLOT 2 */
589 	SLOT = &CH[6].SLOT[SLOT2];
590 	env_out = OPL_CALC_SLOT(SLOT);
591 	if (env_out < EG_ENT-1) {
592 		/* PG */
593 		if (SLOT->vib)
594 			SLOT->Cnt += (SLOT->Incr * vib) >> VIB_RATE_SHIFT;
595 		else
596 			SLOT->Cnt += SLOT->Incr;
597 		/* connection */
598 		outd[0] += OP_OUT(SLOT, env_out, feedback2) * 2;
599 	}
600 
601 	// SD  (17) = mul14[fnum7] + white noise
602 	// TAM (15) = mul15[fnum8]
603 	// TOP (18) = fnum6(mul18[fnum8]+whitenoise)
604 	// HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
605 	env_sd = OPL_CALC_SLOT(SLOT7_2) + whitenoise;
606 	env_tam =OPL_CALC_SLOT(SLOT8_1);
607 	env_top = OPL_CALC_SLOT(SLOT8_2);
608 	env_hh = OPL_CALC_SLOT(SLOT7_1) + whitenoise;
609 
610 	/* PG */
611 	if (SLOT7_1->vib)
612 		SLOT7_1->Cnt += (SLOT7_1->Incr * vib) >> (VIB_RATE_SHIFT-1);
613 	else
614 		SLOT7_1->Cnt += 2 * SLOT7_1->Incr;
615 	if (SLOT7_2->vib)
616 		SLOT7_2->Cnt += (CH[7].fc * vib) >> (VIB_RATE_SHIFT-3);
617 	else
618 		SLOT7_2->Cnt += (CH[7].fc * 8);
619 	if (SLOT8_1->vib)
620 		SLOT8_1->Cnt += (SLOT8_1->Incr * vib) >> VIB_RATE_SHIFT;
621 	else
622 		SLOT8_1->Cnt += SLOT8_1->Incr;
623 	if (SLOT8_2->vib)
624 		SLOT8_2->Cnt += ((CH[8].fc * 3) * vib) >> (VIB_RATE_SHIFT-4);
625 	else
626 		SLOT8_2->Cnt += (CH[8].fc * 48);
627 
628 	tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
629 
630 	/* SD */
631 	if (env_sd < (uint)(EG_ENT - 1))
632 		outd[0] += OP_OUT(SLOT7_1, env_sd, 0) * 8;
633 	/* TAM */
634 	if (env_tam < (uint)(EG_ENT - 1))
635 		outd[0] += OP_OUT(SLOT8_1, env_tam, 0) * 2;
636 	/* TOP-CY */
637 	if (env_top < (uint)(EG_ENT - 1))
638 		outd[0] += OP_OUT(SLOT7_2, env_top, tone8) * 2;
639 	/* HH */
640 	if (env_hh  < (uint)(EG_ENT-1))
641 		outd[0] += OP_OUT(SLOT7_2, env_hh, tone8) * 2;
642 }
643 
644 /* ----------- initialize time tabls ----------- */
init_timetables(FM_OPL * OPL,int ARRATE,int DRRATE)645 static void init_timetables(FM_OPL *OPL, int ARRATE, int DRRATE) {
646 	int i;
647 	double rate;
648 
649 	/* make attack rate & decay rate tables */
650 	for (i = 0; i < 4; i++)
651 		OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
652 	for (i = 4; i <= 60; i++) {
653 		rate = OPL->freqbase;						/* frequency rate */
654 		if (i < 60)
655 			rate *= 1.0 + (i & 3) * 0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
656 		rate *= 1 << ((i >> 2) - 1);						/* b2-5 : shift bit */
657 		rate *= (double)(EG_ENT << ENV_BITS);
658 		OPL->AR_TABLE[i] = (int)(rate / ARRATE);
659 		OPL->DR_TABLE[i] = (int)(rate / DRRATE);
660 	}
661 	for (i = 60; i < 76; i++) {
662 		OPL->AR_TABLE[i] = EG_AED-1;
663 		OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
664 	}
665 }
666 
667 /* ---------- generic table initialize ---------- */
OPLOpenTable(void)668 static int OPLOpenTable(void) {
669 	int s,t;
670 	double rate;
671 	int i,j;
672 	double pom;
673 
674 #ifdef __DS__
675 	DS::fastRamReset();
676 
677 	TL_TABLE = (int *) DS::fastRamAlloc(TL_MAX * 2 * sizeof(int *));
678 	SIN_TABLE = (int **) DS::fastRamAlloc(SIN_ENT * 4 * sizeof(int *));
679 #else
680 
681 	/* allocate dynamic tables */
682 	if ((TL_TABLE = (int *)malloc(TL_MAX * 2 * sizeof(int))) == NULL)
683 		return 0;
684 
685 	if ((SIN_TABLE = (int **)malloc(SIN_ENT * 4 * sizeof(int *))) == NULL) {
686 		free(TL_TABLE);
687 		return 0;
688 	}
689 #endif
690 
691 	if ((AMS_TABLE = (int *)malloc(AMS_ENT * 2 * sizeof(int))) == NULL) {
692 		free(TL_TABLE);
693 		free(SIN_TABLE);
694 		return 0;
695 	}
696 
697 	if ((VIB_TABLE = (int *)malloc(VIB_ENT * 2 * sizeof(int))) == NULL) {
698 		free(TL_TABLE);
699 		free(SIN_TABLE);
700 		free(AMS_TABLE);
701 		return 0;
702 	}
703 	/* make total level table */
704 	for (t = 0; t < EG_ENT - 1; t++) {
705 		rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20);	/* dB -> voltage */
706 		TL_TABLE[         t] =  (int)rate;
707 		TL_TABLE[TL_MAX + t] = -TL_TABLE[t];
708 	}
709 	/* fill volume off area */
710 	for (t = EG_ENT - 1; t < TL_MAX; t++) {
711 		TL_TABLE[t] = TL_TABLE[TL_MAX + t] = 0;
712 	}
713 
714 	/* make sinwave table (total level offet) */
715 	/* degree 0 = degree 180                   = off */
716 	SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1];
717 	for (s = 1;s <= SIN_ENT / 4; s++) {
718 		pom = sin(2 * M_PI * s / SIN_ENT); /* sin     */
719 		pom = 20 * log10(1 / pom);	   /* decibel */
720 		j = int(pom / EG_STEP);         /* TL_TABLE steps */
721 
722 		/* degree 0   -  90    , degree 180 -  90 : plus section */
723 		SIN_TABLE[          s] = SIN_TABLE[SIN_ENT / 2 - s] = &TL_TABLE[j];
724 		/* degree 180 - 270    , degree 360 - 270 : minus section */
725 		SIN_TABLE[SIN_ENT / 2 + s] = SIN_TABLE[SIN_ENT - s] = &TL_TABLE[TL_MAX + j];
726 	}
727 	for (s = 0;s < SIN_ENT; s++) {
728 		SIN_TABLE[SIN_ENT * 1 + s] = s < (SIN_ENT / 2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
729 		SIN_TABLE[SIN_ENT * 2 + s] = SIN_TABLE[s % (SIN_ENT / 2)];
730 		SIN_TABLE[SIN_ENT * 3 + s] = (s / (SIN_ENT / 4)) & 1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT * 2 + s];
731 	}
732 
733 
734 	ENV_CURVE = (int *)malloc(sizeof(int) * (2*EG_ENT+1));
735 	if (!ENV_CURVE)
736 		error("[OPLOpenTable] Cannot allocate memory");
737 
738 	/* envelope counter -> envelope output table */
739 	for (i=0; i < EG_ENT; i++) {
740 		/* ATTACK curve */
741 		pom = pow(((double)(EG_ENT - 1 - i) / EG_ENT), 8) * EG_ENT;
742 		/* if (pom >= EG_ENT) pom = EG_ENT-1; */
743 		ENV_CURVE[i] = (int)pom;
744 		/* DECAY ,RELEASE curve */
745 		ENV_CURVE[(EG_DST >> ENV_BITS) + i]= i;
746 	}
747 	/* off */
748 	ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1;
749 	/* make LFO ams table */
750 	for (i=0; i < AMS_ENT; i++) {
751 		pom = (1.0 + sin(2 * M_PI * i / AMS_ENT)) / 2; /* sin */
752 		AMS_TABLE[i]         = (int)((1.0 / EG_STEP) * pom); /* 1dB   */
753 		AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */
754 	}
755 	/* make LFO vibrate table */
756 	for (i=0; i < VIB_ENT; i++) {
757 		/* 100cent = 1seminote = 6% ?? */
758 		pom = (double)VIB_RATE * 0.06 * sin(2 * M_PI * i / VIB_ENT); /* +-100sect step */
759 		VIB_TABLE[i]         = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */
760 		VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */
761 	}
762 	return 1;
763 }
764 
OPLCloseTable(void)765 static void OPLCloseTable(void) {
766 #ifndef __DS__
767 	free(TL_TABLE);
768 	free(SIN_TABLE);
769 #endif
770 	free(AMS_TABLE);
771 	free(VIB_TABLE);
772 	free(ENV_CURVE);
773 }
774 
775 /* CSM Key Controll */
CSMKeyControll(OPL_CH * CH)776 inline void CSMKeyControll(OPL_CH *CH) {
777 	OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
778 	OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
779 	/* all key off */
780 	OPL_KEYOFF(slot1);
781 	OPL_KEYOFF(slot2);
782 	/* total level latch */
783 	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
784 	slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
785 	/* key on */
786 	CH->op1_out[0] = CH->op1_out[1] = 0;
787 	OPL_KEYON(slot1);
788 	OPL_KEYON(slot2);
789 }
790 
791 /* ---------- opl initialize ---------- */
OPL_initalize(FM_OPL * OPL)792 static void OPL_initalize(FM_OPL *OPL) {
793 	int fn;
794 
795 	/* frequency base */
796 	OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
797 	/* Timer base time */
798 	OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
799 	/* make time tables */
800 	init_timetables(OPL, OPL_ARRATE, OPL_DRRATE);
801 	/* make fnumber -> increment counter table */
802 	for (fn=0; fn < 1024; fn++) {
803 		OPL->FN_TABLE[fn] = (uint)(OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2);
804 	}
805 	/* LFO freq.table */
806 	OPL->amsIncr = (int)(OPL->rate ? (double)AMS_ENT * (1 << AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0);
807 	OPL->vibIncr = (int)(OPL->rate ? (double)VIB_ENT * (1 << VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0);
808 }
809 
810 /* ---------- write a OPL registers ---------- */
OPLWriteReg(FM_OPL * OPL,int r,int v)811 void OPLWriteReg(FM_OPL *OPL, int r, int v) {
812 	OPL_CH *CH;
813 	int slot;
814 	uint block_fnum;
815 
816 	switch (r & 0xe0) {
817 	case 0x00: /* 00-1f:controll */
818 		switch (r & 0x1f) {
819 		case 0x01:
820 			/* wave selector enable */
821 			if (OPL->type&OPL_TYPE_WAVESEL) {
822 				OPL->wavesel = v & 0x20;
823 				if (!OPL->wavesel) {
824 					/* preset compatible mode */
825 					int c;
826 					for (c = 0; c < OPL->max_ch; c++) {
827 						OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
828 						OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
829 					}
830 				}
831 			}
832 			return;
833 		case 0x02:	/* Timer 1 */
834 			OPL->T[0] = (256-v) * 4;
835 			break;
836 		case 0x03:	/* Timer 2 */
837 			OPL->T[1] = (256-v) * 16;
838 			return;
839 		case 0x04:	/* IRQ clear / mask and Timer enable */
840 			if (v & 0x80) {	/* IRQ flag clear */
841 				OPL_STATUS_RESET(OPL, 0x7f);
842 			} else {	/* set IRQ mask ,timer enable*/
843 				uint8 st1 = v & 1;
844 				uint8 st2 = (v >> 1) & 1;
845 				/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
846 				OPL_STATUS_RESET(OPL, v & 0x78);
847 				OPL_STATUSMASK_SET(OPL,((~v) & 0x78) | 0x01);
848 				/* timer 2 */
849 				if (OPL->st[1] != st2) {
850 					double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
851 					OPL->st[1] = st2;
852 					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 1, interval);
853 				}
854 				/* timer 1 */
855 				if (OPL->st[0] != st1) {
856 					double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
857 					OPL->st[0] = st1;
858 					if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam + 0, interval);
859 				}
860 			}
861 			return;
862 		}
863 		break;
864 	case 0x20:	/* am,vib,ksr,eg type,mul */
865 		slot = slot_array[r&0x1f];
866 		if (slot == -1)
867 			return;
868 		set_mul(OPL,slot,v);
869 		return;
870 	case 0x40:
871 		slot = slot_array[r&0x1f];
872 		if (slot == -1)
873 			return;
874 		set_ksl_tl(OPL,slot,v);
875 		return;
876 	case 0x60:
877 		slot = slot_array[r&0x1f];
878 		if (slot == -1)
879 			return;
880 		set_ar_dr(OPL,slot,v);
881 		return;
882 	case 0x80:
883 		slot = slot_array[r&0x1f];
884 		if (slot == -1)
885 			return;
886 		set_sl_rr(OPL,slot,v);
887 		return;
888 	case 0xa0:
889 		switch (r) {
890 		case 0xbd:
891 			/* amsep,vibdep,r,bd,sd,tom,tc,hh */
892 			{
893 			uint8 rkey = OPL->rythm ^ v;
894 			OPL->ams_table = &AMS_TABLE[v & 0x80 ? AMS_ENT : 0];
895 			OPL->vib_table = &VIB_TABLE[v & 0x40 ? VIB_ENT : 0];
896 			OPL->rythm  = v & 0x3f;
897 			if (OPL->rythm & 0x20) {
898 				/* BD key on/off */
899 				if (rkey & 0x10) {
900 					if (v & 0x10) {
901 						OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
902 						OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
903 						OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
904 					} else {
905 						OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
906 						OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
907 					}
908 				}
909 				/* SD key on/off */
910 				if (rkey & 0x08) {
911 					if (v & 0x08)
912 						OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
913 					else
914 						OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
915 				}/* TAM key on/off */
916 				if (rkey & 0x04) {
917 					if (v & 0x04)
918 						OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
919 					else
920 						OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
921 				}
922 				/* TOP-CY key on/off */
923 				if (rkey & 0x02) {
924 					if (v & 0x02)
925 						OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
926 					else
927 						OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
928 				}
929 				/* HH key on/off */
930 				if (rkey & 0x01) {
931 					if (v & 0x01)
932 						OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
933 					else
934 						OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
935 				}
936 			}
937 			}
938 			return;
939 
940 		default:
941 			break;
942 		}
943 		/* keyon,block,fnum */
944 		if ((r & 0x0f) > 8)
945 			return;
946 		CH = &OPL->P_CH[r & 0x0f];
947 		if (!(r&0x10)) {	/* a0-a8 */
948 			block_fnum  = (CH->block_fnum & 0x1f00) | v;
949 		} else {	/* b0-b8 */
950 			int keyon = (v >> 5) & 1;
951 			block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
952 			if (CH->keyon != keyon) {
953 				if ((CH->keyon=keyon)) {
954 					CH->op1_out[0] = CH->op1_out[1] = 0;
955 					OPL_KEYON(&CH->SLOT[SLOT1]);
956 					OPL_KEYON(&CH->SLOT[SLOT2]);
957 				} else {
958 					OPL_KEYOFF(&CH->SLOT[SLOT1]);
959 					OPL_KEYOFF(&CH->SLOT[SLOT2]);
960 				}
961 			}
962 		}
963 		/* update */
964 		if (CH->block_fnum != block_fnum) {
965 			int blockRv = 7 - (block_fnum >> 10);
966 			int fnum = block_fnum & 0x3ff;
967 			CH->block_fnum = block_fnum;
968 			CH->ksl_base = KSL_TABLE[block_fnum >> 6];
969 			CH->fc = OPL->FN_TABLE[fnum] >> blockRv;
970 			CH->kcode = CH->block_fnum >> 9;
971 			if ((OPL->mode & 0x40) && CH->block_fnum & 0x100)
972 				CH->kcode |=1;
973 			CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
974 			CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
975 		}
976 		return;
977 	case 0xc0:
978 		/* FB,C */
979 		if ((r & 0x0f) > 8)
980 			return;
981 		CH = &OPL->P_CH[r&0x0f];
982 		{
983 			int feedback = (v >> 1) & 7;
984 			CH->FB = feedback ? (8 + 1) - feedback : 0;
985 			CH->CON = v & 1;
986 			set_algorythm(CH);
987 		}
988 		return;
989 	case 0xe0: /* wave type */
990 		slot = slot_array[r & 0x1f];
991 		if (slot == -1)
992 			return;
993 		CH = &OPL->P_CH[slot>>1];
994 		if (OPL->wavesel) {
995 			CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v & 0x03) * SIN_ENT];
996 		}
997 		return;
998 	}
999 }
1000 
1001 /* lock/unlock for common table */
OPL_LockTable(void)1002 static int OPL_LockTable(void) {
1003 	num_lock++;
1004 	if (num_lock>1)
1005 		return 0;
1006 	/* first time */
1007 	cur_chip = NULL;
1008 	/* allocate total level table (128kb space) */
1009 	if (!OPLOpenTable()) {
1010 		num_lock--;
1011 		return -1;
1012 	}
1013 	return 0;
1014 }
1015 
OPL_UnLockTable(void)1016 static void OPL_UnLockTable(void) {
1017 	if (num_lock)
1018 		num_lock--;
1019 	if (num_lock)
1020 		return;
1021 	/* last time */
1022 	cur_chip = NULL;
1023 	OPLCloseTable();
1024 }
1025 
1026 /*******************************************************************************/
1027 /*		YM3812 local section                                                   */
1028 /*******************************************************************************/
1029 
1030 /* ---------- update one of chip ----------- */
YM3812UpdateOne(FM_OPL * OPL,int16 * buffer,int length)1031 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) {
1032 	int i;
1033 	int data;
1034 	int16 *buf = buffer;
1035 	uint amsCnt = OPL->amsCnt;
1036 	uint vibCnt = OPL->vibCnt;
1037 	uint8 rythm = OPL->rythm & 0x20;
1038 	OPL_CH *CH, *R_CH;
1039 
1040 
1041 	if ((void *)OPL != cur_chip) {
1042 		cur_chip = (void *)OPL;
1043 		/* channel pointers */
1044 		S_CH = OPL->P_CH;
1045 		E_CH = &S_CH[9];
1046 		/* rythm slot */
1047 		SLOT7_1 = &S_CH[7].SLOT[SLOT1];
1048 		SLOT7_2 = &S_CH[7].SLOT[SLOT2];
1049 		SLOT8_1 = &S_CH[8].SLOT[SLOT1];
1050 		SLOT8_2 = &S_CH[8].SLOT[SLOT2];
1051 		/* LFO state */
1052 		amsIncr = OPL->amsIncr;
1053 		vibIncr = OPL->vibIncr;
1054 		ams_table = OPL->ams_table;
1055 		vib_table = OPL->vib_table;
1056 	}
1057 	R_CH = rythm ? &S_CH[6] : E_CH;
1058 	for (i = 0; i < length; i++) {
1059 		/*            channel A         channel B         channel C      */
1060 		/* LFO */
1061 		ams = ams_table[(amsCnt += amsIncr) >> AMS_SHIFT];
1062 		vib = vib_table[(vibCnt += vibIncr) >> VIB_SHIFT];
1063 		outd[0] = 0;
1064 		/* FM part */
1065 		for (CH = S_CH; CH < R_CH; CH++)
1066 			OPL_CALC_CH(CH);
1067 		/* Rythn part */
1068 		if (rythm)
1069 			OPL_CALC_RH(OPL, S_CH);
1070 		/* limit check */
1071 		data = CLIP(outd[0], OPL_MINOUT, OPL_MAXOUT);
1072 		/* store to sound buffer */
1073 		buf[i] = data >> OPL_OUTSB;
1074 	}
1075 
1076 	OPL->amsCnt = amsCnt;
1077 	OPL->vibCnt = vibCnt;
1078 }
1079 
1080 /* ---------- reset a chip ---------- */
OPLResetChip(FM_OPL * OPL)1081 void OPLResetChip(FM_OPL *OPL) {
1082 	int c,s;
1083 	int i;
1084 
1085 	/* reset chip */
1086 	OPL->mode = 0;	/* normal mode */
1087 	OPL_STATUS_RESET(OPL, 0x7f);
1088 	/* reset with register write */
1089 	OPLWriteReg(OPL, 0x01,0); /* wabesel disable */
1090 	OPLWriteReg(OPL, 0x02,0); /* Timer1 */
1091 	OPLWriteReg(OPL, 0x03,0); /* Timer2 */
1092 	OPLWriteReg(OPL, 0x04,0); /* IRQ mask clear */
1093 	for (i = 0xff; i >= 0x20; i--)
1094 		OPLWriteReg(OPL,i,0);
1095 	/* reset OPerator parameter */
1096 	for (c = 0; c < OPL->max_ch; c++) {
1097 		OPL_CH *CH = &OPL->P_CH[c];
1098 		/* OPL->P_CH[c].PAN = OPN_CENTER; */
1099 		for (s = 0; s < 2; s++) {
1100 			/* wave table */
1101 			CH->SLOT[s].wavetable = &SIN_TABLE[0];
1102 			/* CH->SLOT[s].evm = ENV_MOD_RR; */
1103 			CH->SLOT[s].evc = EG_OFF;
1104 			CH->SLOT[s].eve = EG_OFF + 1;
1105 			CH->SLOT[s].evs = 0;
1106 		}
1107 	}
1108 }
1109 
1110 /* ----------  Create a virtual YM3812 ----------       */
1111 /* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
OPLCreate(int type,int clock,int rate)1112 FM_OPL *OPLCreate(int type, int clock, int rate) {
1113 	char *ptr;
1114 	FM_OPL *OPL;
1115 	int state_size;
1116 	int max_ch = 9; /* normaly 9 channels */
1117 
1118 	if (OPL_LockTable() == -1)
1119 		return NULL;
1120 	/* allocate OPL state space */
1121 	state_size  = sizeof(FM_OPL);
1122 	state_size += sizeof(OPL_CH) * max_ch;
1123 
1124 	/* allocate memory block */
1125 	ptr = (char *)calloc(state_size, 1);
1126 	if (ptr == NULL)
1127 		return NULL;
1128 
1129 	/* clear */
1130 	memset(ptr, 0, state_size);
1131 	OPL       = (FM_OPL *)ptr; ptr += sizeof(FM_OPL);
1132 	OPL->P_CH = (OPL_CH *)ptr; ptr += sizeof(OPL_CH) * max_ch;
1133 
1134 	/* set channel state pointer */
1135 	OPL->type  = type;
1136 	OPL->clock = clock;
1137 	OPL->rate  = rate;
1138 	OPL->max_ch = max_ch;
1139 
1140 	// Init the random source. Note: We use a fixed name for it here.
1141 	// So if multiple FM_OPL objects exist in parallel, then their
1142 	// random sources will have an equal name. At least in the
1143 	// current EventRecorder implementation, this causes no problems;
1144 	// but this is probably not guaranteed.
1145 	// Alas, it does not seem worthwhile to bother much with this
1146 	// at the time, so I am leaving it as it is.
1147 	OPL->rnd = new Common::RandomSource("mame");
1148 
1149 	/* init grobal tables */
1150 	OPL_initalize(OPL);
1151 
1152 	/* reset chip */
1153 	OPLResetChip(OPL);
1154 	return OPL;
1155 }
1156 
1157 /* ----------  Destroy one of virtual YM3812 ----------       */
OPLDestroy(FM_OPL * OPL)1158 void OPLDestroy(FM_OPL *OPL) {
1159 	OPL_UnLockTable();
1160 	delete OPL->rnd;
1161 	free(OPL);
1162 }
1163 
1164 /* ----------  Option handlers ----------       */
OPLSetTimerHandler(FM_OPL * OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)1165 void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,int channelOffset) {
1166 	OPL->TimerHandler   = TimerHandler;
1167 	OPL->TimerParam = channelOffset;
1168 }
1169 
OPLSetIRQHandler(FM_OPL * OPL,OPL_IRQHANDLER IRQHandler,int param)1170 void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
1171 	OPL->IRQHandler     = IRQHandler;
1172 	OPL->IRQParam = param;
1173 }
1174 
OPLSetUpdateHandler(FM_OPL * OPL,OPL_UPDATEHANDLER UpdateHandler,int param)1175 void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler,int param) {
1176 	OPL->UpdateHandler = UpdateHandler;
1177 	OPL->UpdateParam = param;
1178 }
1179 
1180 /* ---------- YM3812 I/O interface ---------- */
OPLWrite(FM_OPL * OPL,int a,int v)1181 int OPLWrite(FM_OPL *OPL,int a,int v) {
1182 	if (!(a & 1)) {	/* address port */
1183 		OPL->address = v & 0xff;
1184 	} else {	/* data port */
1185 		if (OPL->UpdateHandler)
1186 			OPL->UpdateHandler(OPL->UpdateParam,0);
1187 		OPLWriteReg(OPL, OPL->address,v);
1188 	}
1189 	return OPL->status >> 7;
1190 }
1191 
OPLRead(FM_OPL * OPL,int a)1192 unsigned char OPLRead(FM_OPL *OPL,int a) {
1193 	if (!(a & 1)) {	/* status port */
1194 		return OPL->status & (OPL->statusmask | 0x80);
1195 	}
1196 	/* data port */
1197 	switch (OPL->address) {
1198 	case 0x05: /* KeyBoard IN */
1199 		warning("OPL:read unmapped KEYBOARD port");
1200 		return 0;
1201 	case 0x19: /* I/O DATA    */
1202 		warning("OPL:read unmapped I/O port");
1203 		return 0;
1204 	case 0x1a: /* PCM-DATA    */
1205 		return 0;
1206 	default:
1207 		break;
1208 	}
1209 	return 0;
1210 }
1211 
OPLTimerOver(FM_OPL * OPL,int c)1212 int OPLTimerOver(FM_OPL *OPL, int c) {
1213 	if (c) {	/* Timer B */
1214 		OPL_STATUS_SET(OPL, 0x20);
1215 	} else {	/* Timer A */
1216 		OPL_STATUS_SET(OPL, 0x40);
1217 		/* CSM mode key,TL controll */
1218 		if (OPL->mode & 0x80) {	/* CSM mode total level latch and auto key on */
1219 			int ch;
1220 			if (OPL->UpdateHandler)
1221 				OPL->UpdateHandler(OPL->UpdateParam,0);
1222 			for (ch = 0; ch < 9; ch++)
1223 				CSMKeyControll(&OPL->P_CH[ch]);
1224 		}
1225 	}
1226 	/* reload timer */
1227 	if (OPL->TimerHandler)
1228 		(OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c] * OPL->TimerBase);
1229 	return OPL->status >> 7;
1230 }
1231 
makeAdLibOPL(int rate)1232 FM_OPL *makeAdLibOPL(int rate) {
1233 	// We need to emulate one YM3812 chip
1234 	int env_bits = FMOPL_ENV_BITS_HQ;
1235 	int eg_ent = FMOPL_EG_ENT_HQ;
1236 #if defined(_WIN32_WCE) || defined(__SYMBIAN32__) || defined(__GP32__) || defined(GP2X) || defined(__MAEMO__) || defined(__DS__) || defined(__MINT__) || defined(__N64__)
1237 	if (ConfMan.hasKey("FM_high_quality") && ConfMan.getBool("FM_high_quality")) {
1238 		env_bits = FMOPL_ENV_BITS_HQ;
1239 		eg_ent = FMOPL_EG_ENT_HQ;
1240 	} else if (ConfMan.hasKey("FM_medium_quality") && ConfMan.getBool("FM_medium_quality")) {
1241 		env_bits = FMOPL_ENV_BITS_MQ;
1242 		eg_ent = FMOPL_EG_ENT_MQ;
1243 	} else {
1244 		env_bits = FMOPL_ENV_BITS_LQ;
1245 		eg_ent = FMOPL_EG_ENT_LQ;
1246 	}
1247 #endif
1248 
1249 	OPLBuildTables(env_bits, eg_ent);
1250 	return OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
1251 }
1252 
1253 } // End of namespace MAME
1254 } // End of namespace OPL
1255