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  */
22 
23 #include "ultima/nuvie/sound/adplug/opl_class.h"
24 #include "common/scummsys.h"
25 
26 namespace Ultima {
27 namespace Nuvie {
28 
29 #ifndef PI
30 #define PI 3.14159265358979323846
31 #endif
32 
33 #ifdef _MSC_VER
34 #  define INLINE __inline
35 #elif defined(__GNUC__)
36 #  define INLINE inline
37 #else
38 #  define INLINE
39 #endif
40 
41 /* output final shift */
42 #if (OPL_SAMPLE_BITS==16)
43 #define FINAL_SH    (0)
44 #define MAXOUT      (+32767)
45 #define MINOUT      (-32768)
46 #else
47 #define FINAL_SH    (8)
48 #define MAXOUT      (+127)
49 #define MINOUT      (-128)
50 #endif
51 
52 
53 #define FREQ_SH         16  /* 16.16 fixed point (frequency calculations) */
54 #define EG_SH           16  /* 16.16 fixed point (EG timing)              */
55 #define LFO_SH          24  /*  8.24 fixed point (LFO calculations)       */
56 #define TIMER_SH        16  /* 16.16 fixed point (timers calculations)    */
57 
58 #define FREQ_MASK       ((1<<FREQ_SH)-1)
59 
60 /* envelope output entries */
61 #define ENV_BITS        10
62 #define ENV_LEN         (1<<ENV_BITS)
63 #define ENV_STEP        (128.0/ENV_LEN)
64 
65 #define MAX_ATT_INDEX   ((1<<(ENV_BITS-1))-1) /*511*/
66 #define MIN_ATT_INDEX   (0)
67 
68 
69 
70 
71 
72 
73 
74 /* register number to channel number , slot offset */
75 #define SLOT1 0
76 #define SLOT2 1
77 
78 /* Envelope Generator phases */
79 
80 #define EG_ATT          4
81 #define EG_DEC          3
82 #define EG_SUS          2
83 #define EG_REL          1
84 #define EG_OFF          0
85 
86 #define OPL_TYPE_WAVESEL   0x01  /* waveform select     */
87 #define OPL_TYPE_ADPCM     0x02  /* DELTA-T ADPCM unit  */
88 #define OPL_TYPE_KEYBOARD  0x04  /* keyboard interface  */
89 #define OPL_TYPE_IO        0x08  /* I/O port            */
90 
91 /* ---------- Generic interface section ---------- */
92 #define OPL_TYPE_YM3526 (0)
93 #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
94 #define OPL_TYPE_Y8950  (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
95 
96 
97 /* mapping of register number (offset) to slot number used by the emulator */
98 static const int slot_array[32] = {
99 	0, 2, 4, 1, 3, 5, -1, -1,
100 	6, 8, 10, 7, 9, 11, -1, -1,
101 	12, 14, 16, 13, 15, 17, -1, -1,
102 	-1, -1, -1, -1, -1, -1, -1, -1
103 };
104 
105 /* key scale level */
106 /* table is 3dB/octave , DV converts this into 6dB/octave */
107 /* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */
108 #define DV (0.1875/2.0)
109 static const uint32 ksl_tab[8 * 16] = {
110 	/* OCT 0 */
111 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
112 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
113 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
114 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
115 	/* OCT 1 */
116 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
117 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
118 	(uint32)(0.000 / DV), (uint32)(0.750 / DV), (uint32)(1.125 / DV), (uint32)(1.500 / DV),
119 	(uint32)(1.875 / DV), (uint32)(2.250 / DV), (uint32)(2.625 / DV), (uint32)(3.000 / DV),
120 	/* OCT 2 */
121 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV),
122 	(uint32)(0.000 / DV), (uint32)(1.125 / DV), (uint32)(1.875 / DV), (uint32)(2.625 / DV),
123 	(uint32)(3.000 / DV), (uint32)(3.750 / DV), (uint32)(4.125 / DV), (uint32)(4.500 / DV),
124 	(uint32)(4.875 / DV), (uint32)(5.250 / DV), (uint32)(5.625 / DV), (uint32)(6.000 / DV),
125 	/* OCT 3 */
126 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(1.875 / DV),
127 	(uint32)(3.000 / DV), (uint32)(4.125 / DV), (uint32)(4.875 / DV), (uint32)(5.625 / DV),
128 	(uint32)(6.000 / DV), (uint32)(6.750 / DV), (uint32)(7.125 / DV), (uint32)(7.500 / DV),
129 	(uint32)(7.875 / DV), (uint32)(8.250 / DV), (uint32)(8.625 / DV), (uint32)(9.000 / DV),
130 	/* OCT 4 */
131 	(uint32)(0.000 / DV), (uint32)(0.000 / DV), (uint32)(3.000 / DV), (uint32)(4.875 / DV),
132 	(uint32)(6.000 / DV), (uint32)(7.125 / DV), (uint32)(7.875 / DV), (uint32)(8.625 / DV),
133 	(uint32)(9.000 / DV), (uint32)(9.750 / DV), (uint32)(10.125 / DV), (uint32)(10.500 / DV),
134 	(uint32)(10.875 / DV), (uint32)(11.250 / DV), (uint32)(11.625 / DV), (uint32)(12.000 / DV),
135 	/* OCT 5 */
136 	(uint32)(0.000 / DV), (uint32)(3.000 / DV), (uint32)(6.000 / DV), (uint32)(7.875 / DV),
137 	(uint32)(9.000 / DV), (uint32)(10.125 / DV), (uint32)(10.875 / DV), (uint32)(11.625 / DV),
138 	(uint32)(12.000 / DV), (uint32)(12.750 / DV), (uint32)(13.125 / DV), (uint32)(13.500 / DV),
139 	(uint32)(13.875 / DV), (uint32)(14.250 / DV), (uint32)(14.625 / DV), (uint32)(15.000 / DV),
140 	/* OCT 6 */
141 	(uint32)(0.000 / DV), (uint32)(6.000 / DV), (uint32)(9.000 / DV), (uint32)(10.875 / DV),
142 	(uint32)(12.000 / DV), (uint32)(13.125 / DV), (uint32)(13.875 / DV), (uint32)(14.625 / DV),
143 	(uint32)(15.000 / DV), (uint32)(15.750 / DV), (uint32)(16.125 / DV), (uint32)(16.500 / DV),
144 	(uint32)(16.875 / DV), (uint32)(17.250 / DV), (uint32)(17.625 / DV), (uint32)(18.000 / DV),
145 	/* OCT 7 */
146 	(uint32)(0.000 / DV), (uint32)(9.000 / DV), (uint32)(12.000 / DV), (uint32)(13.875 / DV),
147 	(uint32)(15.000 / DV), (uint32)(16.125 / DV), (uint32)(16.875 / DV), (uint32)(17.625 / DV),
148 	(uint32)(18.000 / DV), (uint32)(18.750 / DV), (uint32)(19.125 / DV), (uint32)(19.500 / DV),
149 	(uint32)(19.875 / DV), (uint32)(20.250 / DV), (uint32)(20.625 / DV), (uint32)(21.000 / DV)
150 
151 };
152 #undef DV
153 
154 /* sustain level table (3dB per step) */
155 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
156 #define SC(db) (uint32) ( db * (2.0/ENV_STEP) )
157 static const uint32 sl_tab[16] = {
158 	SC(0), SC(1), SC(2), SC(3), SC(4), SC(5), SC(6), SC(7),
159 	SC(8), SC(9), SC(10), SC(11), SC(12), SC(13), SC(14), SC(31)
160 };
161 #undef SC
162 
163 
164 #define RATE_STEPS (8)
165 static const unsigned char eg_inc[15 * RATE_STEPS] = {
166 
167 	/*cycle:0 1  2 3  4 5  6 7*/
168 
169 	/* 0 */ 0, 1, 0, 1, 0, 1, 0, 1, /* rates 00..12 0 (increment by 0 or 1) */
170 	/* 1 */ 0, 1, 0, 1, 1, 1, 0, 1, /* rates 00..12 1 */
171 	/* 2 */ 0, 1, 1, 1, 0, 1, 1, 1, /* rates 00..12 2 */
172 	/* 3 */ 0, 1, 1, 1, 1, 1, 1, 1, /* rates 00..12 3 */
173 
174 	/* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, /* rate 13 0 (increment by 1) */
175 	/* 5 */ 1, 1, 1, 2, 1, 1, 1, 2, /* rate 13 1 */
176 	/* 6 */ 1, 2, 1, 2, 1, 2, 1, 2, /* rate 13 2 */
177 	/* 7 */ 1, 2, 2, 2, 1, 2, 2, 2, /* rate 13 3 */
178 
179 	/* 8 */ 2, 2, 2, 2, 2, 2, 2, 2, /* rate 14 0 (increment by 2) */
180 	/* 9 */ 2, 2, 2, 4, 2, 2, 2, 4, /* rate 14 1 */
181 	/*10 */ 2, 4, 2, 4, 2, 4, 2, 4, /* rate 14 2 */
182 	/*11 */ 2, 4, 4, 4, 2, 4, 4, 4, /* rate 14 3 */
183 
184 	/*12 */ 4, 4, 4, 4, 4, 4, 4, 4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */
185 	/*13 */ 8, 8, 8, 8, 8, 8, 8, 8, /* rates 15 2, 15 3 for attack */
186 	/*14 */ 0, 0, 0, 0, 0, 0, 0, 0, /* infinity rates for attack and decay(s) */
187 };
188 
189 
190 #define O(a) (a*RATE_STEPS)
191 
192 /*note that there is no O(13) in this table - it's directly in the code */
193 static const unsigned char eg_rate_select[16 + 64 + 16] = { /* Envelope Generator rates (16 + 64 rates + 16 RKS) */
194 	/* 16 dummy (infinite time) rates */
195 	O(14), O(14), O(14), O(14), O(14), O(14), O(14), O(14),
196 	O(14), O(14), O(14), O(14), O(14), O(14), O(14), O(14),
197 
198 	/* rates 00-12 */
199 	O(0), O(1), O(2), O(3),
200 	O(0), O(1), O(2), O(3),
201 	O(0), O(1), O(2), O(3),
202 	O(0), O(1), O(2), O(3),
203 	O(0), O(1), O(2), O(3),
204 	O(0), O(1), O(2), O(3),
205 	O(0), O(1), O(2), O(3),
206 	O(0), O(1), O(2), O(3),
207 	O(0), O(1), O(2), O(3),
208 	O(0), O(1), O(2), O(3),
209 	O(0), O(1), O(2), O(3),
210 	O(0), O(1), O(2), O(3),
211 	O(0), O(1), O(2), O(3),
212 
213 	/* rate 13 */
214 	O(4), O(5), O(6), O(7),
215 
216 	/* rate 14 */
217 	O(8), O(9), O(10), O(11),
218 
219 	/* rate 15 */
220 	O(12), O(12), O(12), O(12),
221 
222 	/* 16 dummy rates (same as 15 3) */
223 	O(12), O(12), O(12), O(12), O(12), O(12), O(12), O(12),
224 	O(12), O(12), O(12), O(12), O(12), O(12), O(12), O(12),
225 
226 };
227 #undef O
228 
229 //rate  0,    1,    2,    3,   4,   5,   6,  7,  8,  9,  10, 11, 12, 13, 14, 15
230 //shift 12,   11,   10,   9,   8,   7,   6,  5,  4,  3,  2,  1,  0,  0,  0,  0
231 //mask  4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7,  3,  1,  0,  0,  0,  0
232 
233 #define O(a) (a*1)
234 static const unsigned char eg_rate_shift[16 + 64 + 16] = { /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */
235 	/* 16 infinite time rates */
236 	O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
237 	O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
238 
239 	/* rates 00-12 */
240 	O(12), O(12), O(12), O(12),
241 	O(11), O(11), O(11), O(11),
242 	O(10), O(10), O(10), O(10),
243 	O(9), O(9), O(9), O(9),
244 	O(8), O(8), O(8), O(8),
245 	O(7), O(7), O(7), O(7),
246 	O(6), O(6), O(6), O(6),
247 	O(5), O(5), O(5), O(5),
248 	O(4), O(4), O(4), O(4),
249 	O(3), O(3), O(3), O(3),
250 	O(2), O(2), O(2), O(2),
251 	O(1), O(1), O(1), O(1),
252 	O(0), O(0), O(0), O(0),
253 
254 	/* rate 13 */
255 	O(0), O(0), O(0), O(0),
256 
257 	/* rate 14 */
258 	O(0), O(0), O(0), O(0),
259 
260 	/* rate 15 */
261 	O(0), O(0), O(0), O(0),
262 
263 	/* 16 dummy rates (same as 15 3) */
264 	O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
265 	O(0), O(0), O(0), O(0), O(0), O(0), O(0), O(0),
266 
267 };
268 #undef O
269 
270 
271 /* multiple table */
272 #define ML 2
273 static const uint8 mul_tab[16] = {
274 	/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */
275 	(uint8)(0.50 * ML), (uint8)(0.00 * ML), (uint8)(0.00 * ML), (uint8)(0.00 * ML), (uint8)(4.00 * ML), (uint8)(0.00 * ML), (uint8)(6.00 * ML), (uint8)(7.00 * ML),
276 	(uint8)(8.00 * ML), (uint8)(9.00 * ML), (uint8)(10.00 * ML), (uint8)(10.00 * ML), (uint8)(12.00 * ML), (uint8)(12.00 * ML), (uint8)(15.00 * ML), (uint8)(15.00 * ML)
277 };
278 #undef ML
279 
280 
281 
282 #define ENV_QUIET       (TL_TAB_LEN>>4)
283 
284 
285 
286 
287 /* LFO Amplitude Modulation table (verified on real YM3812)
288    27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples
289 
290    Length: 210 elements.
291 
292 	Each of the elements has to be repeated
293 	exactly 64 times (on 64 consecutive samples).
294 	The whole table takes: 64 * 210 = 13440 samples.
295 
296 	When AM = 1 data is used directly
297 	When AM = 0 data is divided by 4 before being used (loosing precision is important)
298 */
299 
300 #define LFO_AM_TAB_ELEMENTS 210
301 
302 static const uint8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = {
303 	0, 0, 0, 0, 0, 0, 0,
304 	1, 1, 1, 1,
305 	2, 2, 2, 2,
306 	3, 3, 3, 3,
307 	4, 4, 4, 4,
308 	5, 5, 5, 5,
309 	6, 6, 6, 6,
310 	7, 7, 7, 7,
311 	8, 8, 8, 8,
312 	9, 9, 9, 9,
313 	10, 10, 10, 10,
314 	11, 11, 11, 11,
315 	12, 12, 12, 12,
316 	13, 13, 13, 13,
317 	14, 14, 14, 14,
318 	15, 15, 15, 15,
319 	16, 16, 16, 16,
320 	17, 17, 17, 17,
321 	18, 18, 18, 18,
322 	19, 19, 19, 19,
323 	20, 20, 20, 20,
324 	21, 21, 21, 21,
325 	22, 22, 22, 22,
326 	23, 23, 23, 23,
327 	24, 24, 24, 24,
328 	25, 25, 25, 25,
329 	26, 26, 26,
330 	25, 25, 25, 25,
331 	24, 24, 24, 24,
332 	23, 23, 23, 23,
333 	22, 22, 22, 22,
334 	21, 21, 21, 21,
335 	20, 20, 20, 20,
336 	19, 19, 19, 19,
337 	18, 18, 18, 18,
338 	17, 17, 17, 17,
339 	16, 16, 16, 16,
340 	15, 15, 15, 15,
341 	14, 14, 14, 14,
342 	13, 13, 13, 13,
343 	12, 12, 12, 12,
344 	11, 11, 11, 11,
345 	10, 10, 10, 10,
346 	9, 9, 9, 9,
347 	8, 8, 8, 8,
348 	7, 7, 7, 7,
349 	6, 6, 6, 6,
350 	5, 5, 5, 5,
351 	4, 4, 4, 4,
352 	3, 3, 3, 3,
353 	2, 2, 2, 2,
354 	1, 1, 1, 1
355 };
356 
357 /* LFO Phase Modulation table (verified on real YM3812) */
358 static const int8 lfo_pm_table[8 * 8 * 2] = {
359 
360 	/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */
361 	0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
362 	0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/
363 
364 	/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */
365 	0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
366 	1, 0, 0, 0, -1, 0, 0, 0, /*LFO PM depth = 1*/
367 
368 	/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */
369 	1, 0, 0, 0, -1, 0, 0, 0, /*LFO PM depth = 0*/
370 	2, 1, 0, -1, -2, -1, 0, 1, /*LFO PM depth = 1*/
371 
372 	/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */
373 	1, 0, 0, 0, -1, 0, 0, 0, /*LFO PM depth = 0*/
374 	3, 1, 0, -1, -3, -1, 0, 1, /*LFO PM depth = 1*/
375 
376 	/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */
377 	2, 1, 0, -1, -2, -1, 0, 1, /*LFO PM depth = 0*/
378 	4, 2, 0, -2, -4, -2, 0, 2, /*LFO PM depth = 1*/
379 
380 	/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */
381 	2, 1, 0, -1, -2, -1, 0, 1, /*LFO PM depth = 0*/
382 	5, 2, 0, -2, -5, -2, 0, 2, /*LFO PM depth = 1*/
383 
384 	/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */
385 	3, 1, 0, -1, -3, -1, 0, 1, /*LFO PM depth = 0*/
386 	6, 3, 0, -3, -6, -3, 0, 3, /*LFO PM depth = 1*/
387 
388 	/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */
389 	3, 1, 0, -1, -3, -1, 0, 1, /*LFO PM depth = 0*/
390 	7, 3, 0, -3, -7, -3, 0, 3 /*LFO PM depth = 1*/
391 };
392 
393 
OplClass(int rate,bool bit16,bool usestereo)394 OplClass::OplClass(int rate, bool bit16, bool usestereo)
395 	: use16bit(bit16), stereo(usestereo), oplRate(rate) {
396 	YM3812NumChips = 0;
397 	num_lock = 0;
398 	cur_chip = NULL;
399 	YM3812Init(1, 3579545, rate);
400 }
401 
update(short * buf,int samples)402 void OplClass::update(short *buf, int samples) {
403 	int i;
404 
405 	if (use16bit) {
406 		YM3812UpdateOne(0, buf, samples);
407 
408 		if (stereo)
409 			for (i = samples - 1; i >= 0; i--) {
410 				buf[i * 2] = buf[i];
411 				buf[i * 2 + 1] = buf[i];
412 			}
413 	} else {
414 		short *tempbuf = new short[stereo ? samples * 2 : samples];
415 		YM3812UpdateOne(0, tempbuf, samples);
416 
417 		if (stereo)
418 			for (i = samples - 1; i >= 0; i--) {
419 				tempbuf[i * 2] = tempbuf[i];
420 				tempbuf[i * 2 + 1] = tempbuf[i];
421 			}
422 
423 		for (i = 0; i < (stereo ? samples * 2 : samples); i++)
424 			((char *)buf)[i] = (tempbuf[i] >> 8) ^ 0x80;
425 
426 		delete [] tempbuf;
427 	}
428 }
429 
write(int reg,int val)430 void OplClass::write(int reg, int val) {
431 	YM3812Write(0, 0, reg);
432 	YM3812Write(0, 1, val);
433 }
434 
init()435 void OplClass::init() {
436 	YM3812ResetChip(0);
437 }
438 
limit(int val,int max,int min)439 INLINE int limit(int val, int max, int min) {
440 	if (val > max)
441 		val = max;
442 	else if (val < min)
443 		val = min;
444 
445 	return val;
446 }
447 
448 
449 /* status set and IRQ handling */
OPL_STATUS_SET(FM_OPL * OPL,int flag)450 INLINE void OPL_STATUS_SET(FM_OPL *OPL, int flag) {
451 	/* set status flag */
452 	OPL->status |= flag;
453 	if (!(OPL->status & 0x80)) {
454 		if (OPL->status & OPL->statusmask) {
455 			/* IRQ on */
456 			OPL->status |= 0x80;
457 			/* callback user interrupt handler (IRQ is OFF to ON) */
458 			if (OPL->IRQHandler)(OPL->IRQHandler)(OPL->IRQParam, 1);
459 		}
460 	}
461 }
462 
463 /* status reset and IRQ handling */
OPL_STATUS_RESET(FM_OPL * OPL,int flag)464 INLINE void OPL_STATUS_RESET(FM_OPL *OPL, int flag) {
465 	/* reset status flag */
466 	OPL->status &= ~flag;
467 	if ((OPL->status & 0x80)) {
468 		if (!(OPL->status & OPL->statusmask)) {
469 			OPL->status &= 0x7f;
470 			/* callback user interrupt handler (IRQ is ON to OFF) */
471 			if (OPL->IRQHandler)(OPL->IRQHandler)(OPL->IRQParam, 0);
472 		}
473 	}
474 }
475 
476 /* IRQ mask set */
OPL_STATUSMASK_SET(FM_OPL * OPL,int flag)477 INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL, int flag) {
478 	OPL->statusmask = flag;
479 	/* IRQ handling check */
480 	OPL_STATUS_SET(OPL, 0);
481 	OPL_STATUS_RESET(OPL, 0);
482 }
483 
484 
485 /* advance LFO to next sample */
advance_lfo(FM_OPL * OPL)486 INLINE void OplClass::advance_lfo(FM_OPL *OPL) {
487 	uint8 tmp;
488 
489 	/* LFO */
490 	OPL->lfo_am_cnt += OPL->lfo_am_inc;
491 	if (OPL->lfo_am_cnt >= (uint32)(LFO_AM_TAB_ELEMENTS << LFO_SH)) /* lfo_am_table is 210 elements long */
492 		OPL->lfo_am_cnt -= (uint32)(LFO_AM_TAB_ELEMENTS << LFO_SH);
493 
494 	tmp = lfo_am_table[ OPL->lfo_am_cnt >> LFO_SH ];
495 
496 	if (OPL->lfo_am_depth)
497 		LFO_AM = tmp;
498 	else
499 		LFO_AM = tmp >> 2;
500 
501 	OPL->lfo_pm_cnt += OPL->lfo_pm_inc;
502 	LFO_PM = ((OPL->lfo_pm_cnt >> LFO_SH) & 7) | OPL->lfo_pm_depth_range;
503 }
504 
505 /* advance to next sample */
advancex(FM_OPL * OPL)506 INLINE void OplClass::advancex(FM_OPL *OPL) {
507 	OPL_CH *CH;
508 	OPL_SLOT *op;
509 	int i;
510 
511 	OPL->eg_timer += OPL->eg_timer_add;
512 
513 	while (OPL->eg_timer >= OPL->eg_timer_overflow) {
514 		OPL->eg_timer -= OPL->eg_timer_overflow;
515 
516 		OPL->eg_cnt++;
517 
518 		for (i = 0; i < 9 * 2; i++) {
519 			CH  = &OPL->P_CH[i / 2];
520 			op  = &CH->SLOT[i & 1];
521 
522 			/* Envelope Generator */
523 			switch (op->state) {
524 			case EG_ATT: {      /* attack phase */
525 
526 				if (!(OPL->eg_cnt & ((1 << op->eg_sh_ar) - 1))) {
527 					op->volume += (~op->volume *
528 					               (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt >> op->eg_sh_ar) & 7)])
529 					              ) >> 3;
530 
531 					if (op->volume <= MIN_ATT_INDEX) {
532 						op->volume = MIN_ATT_INDEX;
533 						op->state = EG_DEC;
534 					}
535 
536 				}
537 
538 			}
539 			break;
540 
541 			case EG_DEC:    /* decay phase */
542 				if (!(OPL->eg_cnt & ((1 << op->eg_sh_dr) - 1))) {
543 					op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt >> op->eg_sh_dr) & 7)];
544 
545 					if (op->volume >= (int32)op->sl)
546 						op->state = EG_SUS;
547 
548 				}
549 				break;
550 
551 			case EG_SUS:    /* sustain phase */
552 
553 				/* this is important behaviour:
554 				one can change percusive/non-percussive modes on the fly and
555 				the chip will remain in sustain phase - verified on real YM3812 */
556 
557 				if (op->eg_type) {  /* non-percussive mode */
558 					/* do nothing */
559 				} else {            /* percussive mode */
560 					/* during sustain phase chip adds Release Rate (in percussive mode) */
561 					if (!(OPL->eg_cnt & ((1 << op->eg_sh_rr) - 1))) {
562 						op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt >> op->eg_sh_rr) & 7)];
563 
564 						if (op->volume >= MAX_ATT_INDEX)
565 							op->volume = MAX_ATT_INDEX;
566 					}
567 					/* else do nothing in sustain phase */
568 				}
569 				break;
570 
571 			case EG_REL:    /* release phase */
572 				if (!(OPL->eg_cnt & ((1 << op->eg_sh_rr) - 1))) {
573 					op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt >> op->eg_sh_rr) & 7)];
574 
575 					if (op->volume >= MAX_ATT_INDEX) {
576 						op->volume = MAX_ATT_INDEX;
577 						op->state = EG_OFF;
578 					}
579 
580 				}
581 				break;
582 
583 			default:
584 				break;
585 			}
586 		}
587 	}
588 
589 	for (i = 0; i < 9 * 2; i++) {
590 		CH  = &OPL->P_CH[i / 2];
591 		op  = &CH->SLOT[i & 1];
592 
593 		/* Phase Generator */
594 		if (op->vib) {
595 			uint8 block;
596 			unsigned int block_fnum = CH->block_fnum;
597 
598 			unsigned int fnum_lfo   = (block_fnum & 0x0380) >> 7;
599 
600 			signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16 * fnum_lfo ];
601 
602 			if (lfo_fn_table_index_offset) { /* LFO phase modulation active */
603 				block_fnum += lfo_fn_table_index_offset;
604 				block = (block_fnum & 0x1c00) >> 10;
605 				op->Cnt += (OPL->fn_tab[block_fnum & 0x03ff] >> (7 - block)) * op->mul; //ok
606 			} else { /* LFO phase modulation  = zero */
607 				op->Cnt += op->Incr;
608 			}
609 		} else { /* LFO phase modulation disabled for this operator */
610 			op->Cnt += op->Incr;
611 		}
612 	}
613 
614 	/*  The Noise Generator of the YM3812 is 23-bit shift register.
615 	*   Period is equal to 2^23-2 samples.
616 	*   Register works at sampling frequency of the chip, so output
617 	*   can change on every sample.
618 	*
619 	*   Output of the register and input to the bit 22 is:
620 	*   bit0 XOR bit14 XOR bit15 XOR bit22
621 	*
622 	*   Simply use bit 22 as the noise output.
623 	*/
624 
625 	OPL->noise_p += OPL->noise_f;
626 	i = OPL->noise_p >> FREQ_SH;        /* number of events (shifts of the shift register) */
627 	OPL->noise_p &= FREQ_MASK;
628 	while (i) {
629 		/*
630 		uint32 j;
631 		j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1;
632 		OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1);
633 		*/
634 
635 		/*
636 		    Instead of doing all the logic operations above, we
637 		    use a trick here (and use bit 0 as the noise output).
638 		    The difference is only that the noise bit changes one
639 		    step ahead. This doesn't matter since we don't know
640 		    what is real state of the noise_rng after the reset.
641 		*/
642 
643 		if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302;
644 		OPL->noise_rng >>= 1;
645 
646 		i--;
647 	}
648 }
649 
650 
op_calc(uint32 phase,unsigned int env,signed int pm,unsigned int wave_tab)651 INLINE signed int OplClass::op_calc(uint32 phase, unsigned int env, signed int pm, unsigned int wave_tab) {
652 	uint32 p;
653 
654 	p = (env << 4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm << 16))) >> FREQ_SH) & SIN_MASK) ];
655 
656 	if (p >= TL_TAB_LEN)
657 		return 0;
658 	return tl_tab[p];
659 }
660 
op_calc1(uint32 phase,unsigned int env,signed int pm,unsigned int wave_tab)661 INLINE signed int OplClass::op_calc1(uint32 phase, unsigned int env, signed int pm, unsigned int wave_tab) {
662 	uint32 p;
663 	int32  i;
664 
665 	i = (phase & ~FREQ_MASK) + pm;
666 
667 	/*logerror("i=%08x (i>>16)&511=%8i phase=%i [pm=%08x] ",i, (i>>16)&511, phase>>FREQ_SH, pm);*/
668 
669 	p = (env << 4) + sin_tab[ wave_tab + ((i >> FREQ_SH) & SIN_MASK)];
670 
671 	/*logerror("(p&255=%i p>>8=%i) out= %i\n", p&255,p>>8, tl_tab[p&255]>>(p>>8) );*/
672 
673 	if (p >= TL_TAB_LEN)
674 		return 0;
675 	return tl_tab[p];
676 }
677 
678 
679 #define volume_calc(OP) ((OP)->TLL + ((uint32)(OP)->volume) + (LFO_AM & (OP)->AMmask))
680 
681 /* calculate output */
OPL_CALC_CH(OPL_CH * CH)682 INLINE void OplClass::OPL_CALC_CH(OPL_CH *CH) {
683 	OPL_SLOT *SLOT;
684 	unsigned int env;
685 	signed int out;
686 
687 	phase_modulation = 0;
688 
689 	/* SLOT 1 */
690 	SLOT = &CH->SLOT[SLOT1];
691 	env  = volume_calc(SLOT);
692 	out  = SLOT->op1_out[0] + SLOT->op1_out[1];
693 	SLOT->op1_out[0] = SLOT->op1_out[1];
694 	*SLOT->connect1 += SLOT->op1_out[0];
695 	SLOT->op1_out[1] = 0;
696 	if (env < ENV_QUIET) {
697 		if (!SLOT->FB)
698 			out = 0;
699 		SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out << SLOT->FB), SLOT->wavetable);
700 	}
701 
702 	/* SLOT 2 */
703 	SLOT++;
704 	env = volume_calc(SLOT);
705 	if (env < ENV_QUIET)
706 		output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable);
707 }
708 
709 /*
710 	operators used in the rhythm sounds generation process:
711 
712 	Envelope Generator:
713 
714 channel  operator  register number   Bass  High  Snare Tom  Top
715 / slot   number    TL ARDR SLRR Wave Drum  Hat   Drum  Tom  Cymbal
716  6 / 0   12        50  70   90   f0  +
717  6 / 1   15        53  73   93   f3  +
718  7 / 0   13        51  71   91   f1        +
719  7 / 1   16        54  74   94   f4              +
720  8 / 0   14        52  72   92   f2                    +
721  8 / 1   17        55  75   95   f5                          +
722 
723 	Phase Generator:
724 
725 channel  operator  register number   Bass  High  Snare Tom  Top
726 / slot   number    MULTIPLE          Drum  Hat   Drum  Tom  Cymbal
727  6 / 0   12        30                +
728  6 / 1   15        33                +
729  7 / 0   13        31                      +     +           +
730  7 / 1   16        34                -----  n o t  u s e d -----
731  8 / 0   14        32                                  +
732  8 / 1   17        35                      +                 +
733 
734 channel  operator  register number   Bass  High  Snare Tom  Top
735 number   number    BLK/FNUM2 FNUM    Drum  Hat   Drum  Tom  Cymbal
736    6     12,15     B6        A6      +
737 
738    7     13,16     B7        A7            +     +           +
739 
740    8     14,17     B8        A8            +           +     +
741 
742 */
743 
744 /* calculate rhythm */
745 
OPL_CALC_RH(OPL_CH * CH,unsigned int noise)746 INLINE void OplClass::OPL_CALC_RH(OPL_CH *CH, unsigned int noise) {
747 	OPL_SLOT *SLOT;
748 	signed int out;
749 	unsigned int env;
750 
751 
752 	/* Bass Drum (verified on real YM3812):
753 	  - depends on the channel 6 'connect' register:
754 	      when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out)
755 	      when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored
756 	  - output sample always is multiplied by 2
757 	*/
758 
759 	phase_modulation = 0;
760 	/* SLOT 1 */
761 	SLOT = &CH[6].SLOT[SLOT1];
762 	env = volume_calc(SLOT);
763 
764 	out = SLOT->op1_out[0] + SLOT->op1_out[1];
765 	SLOT->op1_out[0] = SLOT->op1_out[1];
766 
767 	if (!SLOT->CON)
768 		phase_modulation = SLOT->op1_out[0];
769 	//else ignore output of operator 1
770 
771 	SLOT->op1_out[1] = 0;
772 	if (env < ENV_QUIET) {
773 		if (!SLOT->FB)
774 			out = 0;
775 		SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out << SLOT->FB), SLOT->wavetable);
776 	}
777 
778 	/* SLOT 2 */
779 	SLOT++;
780 	env = volume_calc(SLOT);
781 	if (env < ENV_QUIET)
782 		output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2;
783 
784 
785 	/* Phase generation is based on: */
786 	// HH  (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases)
787 	// SD  (16) channel 7->slot 1
788 	// TOM (14) channel 8->slot 1
789 	// TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases)
790 
791 	/* Envelope generation based on: */
792 	// HH  channel 7->slot1
793 	// SD  channel 7->slot2
794 	// TOM channel 8->slot1
795 	// TOP channel 8->slot2
796 
797 
798 	/* The following formulas can be well optimized.
799 	   I leave them in direct form for now (in case I've missed something).
800 	*/
801 
802 	/* High Hat (verified on real YM3812) */
803 	env = volume_calc(SLOT7_1);
804 	if (env < ENV_QUIET) {
805 
806 		/* high hat phase generation:
807 		    phase = d0 or 234 (based on frequency only)
808 		    phase = 34 or 2d0 (based on noise)
809 		*/
810 
811 		/* base frequency derived from operator 1 in channel 7 */
812 		unsigned char bit7 = ((SLOT7_1->Cnt >> FREQ_SH) >> 7) & 1;
813 		unsigned char bit3 = ((SLOT7_1->Cnt >> FREQ_SH) >> 3) & 1;
814 		unsigned char bit2 = ((SLOT7_1->Cnt >> FREQ_SH) >> 2) & 1;
815 
816 		unsigned char res1 = (bit2 ^ bit7) | bit3;
817 
818 		/* when res1 = 0 phase = 0x000 | 0xd0; */
819 		/* when res1 = 1 phase = 0x200 | (0xd0>>2); */
820 		uint32 phase = res1 ? (0x200 | (0xd0 >> 2)) : 0xd0;
821 
822 		/* enable gate based on frequency of operator 2 in channel 8 */
823 		unsigned char bit5e = ((SLOT8_2->Cnt >> FREQ_SH) >> 5) & 1;
824 		unsigned char bit3e = ((SLOT8_2->Cnt >> FREQ_SH) >> 3) & 1;
825 
826 		unsigned char res2 = (bit3e ^ bit5e);
827 
828 		/* when res2 = 0 pass the phase from calculation above (res1); */
829 		/* when res2 = 1 phase = 0x200 | (0xd0>>2); */
830 		if (res2)
831 			phase = (0x200 | (0xd0 >> 2));
832 
833 
834 		/* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
835 		/* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
836 		if (phase & 0x200) {
837 			if (noise)
838 				phase = 0x200 | 0xd0;
839 		} else
840 			/* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */
841 			/* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */
842 		{
843 			if (noise)
844 				phase = 0xd0 >> 2;
845 		}
846 
847 		output[0] += op_calc(phase << FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
848 	}
849 
850 	/* Snare Drum (verified on real YM3812) */
851 	env = volume_calc(SLOT7_2);
852 	if (env < ENV_QUIET) {
853 		/* base frequency derived from operator 1 in channel 7 */
854 		unsigned char bit8 = ((SLOT7_1->Cnt >> FREQ_SH) >> 8) & 1;
855 
856 		/* when bit8 = 0 phase = 0x100; */
857 		/* when bit8 = 1 phase = 0x200; */
858 		uint32 phase = bit8 ? 0x200 : 0x100;
859 
860 		/* Noise bit XOR'es phase by 0x100 */
861 		/* when noisebit = 0 pass the phase from calculation above */
862 		/* when noisebit = 1 phase ^= 0x100; */
863 		/* in other words: phase ^= (noisebit<<8); */
864 		if (noise)
865 			phase ^= 0x100;
866 
867 		output[0] += op_calc(phase << FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
868 	}
869 
870 	/* Tom Tom (verified on real YM3812) */
871 	env = volume_calc(SLOT8_1);
872 	if (env < ENV_QUIET)
873 		output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2;
874 
875 	/* Top Cymbal (verified on real YM3812) */
876 	env = volume_calc(SLOT8_2);
877 	if (env < ENV_QUIET) {
878 		/* base frequency derived from operator 1 in channel 7 */
879 		unsigned char bit7 = ((SLOT7_1->Cnt >> FREQ_SH) >> 7) & 1;
880 		unsigned char bit3 = ((SLOT7_1->Cnt >> FREQ_SH) >> 3) & 1;
881 		unsigned char bit2 = ((SLOT7_1->Cnt >> FREQ_SH) >> 2) & 1;
882 
883 		unsigned char res1 = (bit2 ^ bit7) | bit3;
884 
885 		/* when res1 = 0 phase = 0x000 | 0x100; */
886 		/* when res1 = 1 phase = 0x200 | 0x100; */
887 		uint32 phase = res1 ? 0x300 : 0x100;
888 
889 		/* enable gate based on frequency of operator 2 in channel 8 */
890 		unsigned char bit5e = ((SLOT8_2->Cnt >> FREQ_SH) >> 5) & 1;
891 		unsigned char bit3e = ((SLOT8_2->Cnt >> FREQ_SH) >> 3) & 1;
892 
893 		unsigned char res2 = (bit3e ^ bit5e);
894 		/* when res2 = 0 pass the phase from calculation above (res1); */
895 		/* when res2 = 1 phase = 0x200 | 0x100; */
896 		if (res2)
897 			phase = 0x300;
898 
899 		output[0] += op_calc(phase << FREQ_SH, env, 0, SLOT8_2->wavetable) * 2;
900 	}
901 
902 }
903 
904 
905 /* generic table initialize */
init_tables(void)906 int OplClass::init_tables(void) {
907 	signed int i, x;
908 	signed int n;
909 	double o, m;
910 
911 
912 	for (x = 0; x < TL_RES_LEN; x++) {
913 		m = (1 << 16) / pow(2, (x + 1) * (ENV_STEP / 4.0) / 8.0);
914 		m = floor(m);
915 
916 		/* we never reach (1<<16) here due to the (x+1) */
917 		/* result fits within 16 bits at maximum */
918 
919 		n = (int)m;     /* 16 bits here */
920 		n >>= 4;        /* 12 bits here */
921 		if (n & 1)      /* round to nearest */
922 			n = (n >> 1) + 1;
923 		else
924 			n = n >> 1;
925 		/* 11 bits here (rounded) */
926 		n <<= 1;        /* 12 bits here (as in real chip) */
927 		tl_tab[ x * 2 + 0 ] = n;
928 		tl_tab[ x * 2 + 1 ] = -tl_tab[ x * 2 + 0 ];
929 
930 		for (i = 1; i < 12; i++) {
931 			tl_tab[ x * 2 + 0 + i * 2 * TL_RES_LEN ] =  tl_tab[ x * 2 + 0 ] >> i;
932 			tl_tab[ x * 2 + 1 + i * 2 * TL_RES_LEN ] = -tl_tab[ x * 2 + 0 + i * 2 * TL_RES_LEN ];
933 		}
934 	}
935 	/*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
936 
937 
938 	for (i = 0; i < SIN_LEN; i++) {
939 		/* non-standard sinus */
940 		m = sin(((i * 2) + 1) * PI / SIN_LEN); /* checked against the real chip */
941 
942 		/* we never reach zero here due to ((i*2)+1) */
943 
944 		if (m > 0.0)
945 			o = 8 * log(1.0 / m) / log(2); /* convert to 'decibels' */
946 		else
947 			o = 8 * log(-1.0 / m) / log(2); /* convert to 'decibels' */
948 
949 		o = o / (ENV_STEP / 4);
950 
951 		n = (int)(2.0 * o);
952 		if (n & 1)                      /* round to nearest */
953 			n = (n >> 1) + 1;
954 		else
955 			n = n >> 1;
956 
957 		sin_tab[ i ] = n * 2 + (m >= 0.0 ? 0 : 1);
958 
959 		/*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/
960 	}
961 
962 	for (i = 0; i < SIN_LEN; i++) {
963 		/* waveform 1:  __      __     */
964 		/*             /  \____/  \____*/
965 		/* output only first half of the sinus waveform (positive one) */
966 
967 		if (i & (1 << (SIN_BITS - 1)))
968 			sin_tab[1 * SIN_LEN + i] = TL_TAB_LEN;
969 		else
970 			sin_tab[1 * SIN_LEN + i] = sin_tab[i];
971 
972 		/* waveform 2:  __  __  __  __ */
973 		/*             /  \/  \/  \/  \*/
974 		/* abs(sin) */
975 
976 		sin_tab[2 * SIN_LEN + i] = sin_tab[i & (SIN_MASK >> 1) ];
977 
978 		/* waveform 3:  _   _   _   _  */
979 		/*             / |_/ |_/ |_/ |_*/
980 		/* abs(output only first quarter of the sinus waveform) */
981 
982 		if (i & (1 << (SIN_BITS - 2)))
983 			sin_tab[3 * SIN_LEN + i] = TL_TAB_LEN;
984 		else
985 			sin_tab[3 * SIN_LEN + i] = sin_tab[i & (SIN_MASK >> 2)];
986 
987 		/*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] );
988 		logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] );
989 		logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/
990 	}
991 	/*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/
992 
993 	return 1;
994 }
995 
OPLCloseTable(void)996 static void OPLCloseTable(void) {
997 #ifdef SAVE_SAMPLE
998 	fclose(sample[0]);
999 #endif
1000 }
1001 
1002 
1003 
OPL_initalize(FM_OPL * OPL)1004 static void OPL_initalize(FM_OPL *OPL) {
1005 	int i;
1006 
1007 	/* frequency base */
1008 	OPL->freqbase  = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate  : 0;
1009 
1010 
1011 	/* Timer base time */
1012 	OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0);
1013 
1014 	/* make fnumber -> increment counter table */
1015 	for (i = 0 ; i < 1024 ; i++) {
1016 		/* opn phase increment counter = 20bit */
1017 		OPL->fn_tab[i] = (uint32)((double)i * 64 * OPL->freqbase * (1 << (FREQ_SH - 10))); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
1018 	}
1019 
1020 
1021 	/* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */
1022 	/* One entry from LFO_AM_TABLE lasts for 64 samples */
1023 	OPL->lfo_am_inc = (1.0 / 64.0) * (1 << LFO_SH) * OPL->freqbase;
1024 
1025 	/* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */
1026 	OPL->lfo_pm_inc = (1.0 / 1024.0) * (1 << LFO_SH) * OPL->freqbase;
1027 
1028 	/*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/
1029 
1030 	/* Noise generator: a step takes 1 sample */
1031 	OPL->noise_f = (1.0 / 1.0) * (1 << FREQ_SH) * OPL->freqbase;
1032 
1033 	OPL->eg_timer_add  = (1 << EG_SH)  * OPL->freqbase;
1034 	OPL->eg_timer_overflow = (1) * (1 << EG_SH);
1035 	/*logerror("OPLinit eg_timer_add=%8x eg_timer_overflow=%8x\n", OPL->eg_timer_add, OPL->eg_timer_overflow);*/
1036 
1037 }
1038 
FM_KEYON(OPL_SLOT * SLOT,uint32 key_set)1039 INLINE void FM_KEYON(OPL_SLOT *SLOT, uint32 key_set) {
1040 	if (!SLOT->key) {
1041 		/* restart Phase Generator */
1042 		SLOT->Cnt = 0;
1043 		/* phase -> Attack */
1044 		SLOT->state = EG_ATT;
1045 	}
1046 	SLOT->key |= key_set;
1047 }
1048 
FM_KEYOFF(OPL_SLOT * SLOT,uint32 key_clr)1049 INLINE void FM_KEYOFF(OPL_SLOT *SLOT, uint32 key_clr) {
1050 	if (SLOT->key) {
1051 		SLOT->key &= key_clr;
1052 
1053 		if (!SLOT->key) {
1054 			/* phase -> Release */
1055 			if (SLOT->state > EG_REL)
1056 				SLOT->state = EG_REL;
1057 		}
1058 	}
1059 }
1060 
1061 /* update phase increment counter of operator (also update the EG rates if necessary) */
CALC_FCSLOT(OPL_CH * CH,OPL_SLOT * SLOT)1062 INLINE void CALC_FCSLOT(OPL_CH *CH, OPL_SLOT *SLOT) {
1063 	int ksr;
1064 
1065 	/* (frequency) phase increment counter */
1066 	SLOT->Incr = CH->fc * SLOT->mul;
1067 	ksr = CH->kcode >> SLOT->KSR;
1068 
1069 	if (SLOT->ksr != ksr) {
1070 		SLOT->ksr = ksr;
1071 
1072 		/* calculate envelope generator rates */
1073 		if ((SLOT->ar + SLOT->ksr) < 16 + 62) {
1074 			SLOT->eg_sh_ar  = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1075 			SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1076 		} else {
1077 			SLOT->eg_sh_ar  = 0;
1078 			SLOT->eg_sel_ar = 13 * RATE_STEPS;
1079 		}
1080 		SLOT->eg_sh_dr  = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1081 		SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1082 		SLOT->eg_sh_rr  = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1083 		SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1084 	}
1085 }
1086 
1087 /* set multi,am,vib,EG-TYP,KSR,mul */
set_mul(FM_OPL * OPL,int slot,int v)1088 INLINE void set_mul(FM_OPL *OPL, int slot, int v) {
1089 	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
1090 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1091 
1092 	SLOT->mul     = mul_tab[v & 0x0f];
1093 	SLOT->KSR     = (v & 0x10) ? 0 : 2;
1094 	SLOT->eg_type = (v & 0x20);
1095 	SLOT->vib     = (v & 0x40);
1096 	SLOT->AMmask  = (v & 0x80) ? ~0 : 0;
1097 	CALC_FCSLOT(CH, SLOT);
1098 }
1099 
1100 /* set ksl & tl */
set_ksl_tl(FM_OPL * OPL,int slot,int v)1101 INLINE void set_ksl_tl(FM_OPL *OPL, int slot, int v) {
1102 	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
1103 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1104 	int ksl = v >> 6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */
1105 
1106 	SLOT->ksl = ksl ? 3 - ksl : 31;
1107 	SLOT->TL  = (v & 0x3f) << (ENV_BITS - 1 - 7); /* 7 bits TL (bit 6 = always 0) */
1108 
1109 	SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
1110 }
1111 
1112 /* set attack rate & decay rate  */
set_ar_dr(FM_OPL * OPL,int slot,int v)1113 INLINE void set_ar_dr(FM_OPL *OPL, int slot, int v) {
1114 	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
1115 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1116 
1117 	SLOT->ar = (v >> 4)  ? 16 + ((v >> 4)  << 2) : 0;
1118 
1119 	if ((SLOT->ar + SLOT->ksr) < 16 + 62) {
1120 		SLOT->eg_sh_ar  = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1121 		SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1122 	} else {
1123 		SLOT->eg_sh_ar  = 0;
1124 		SLOT->eg_sel_ar = 13 * RATE_STEPS;
1125 	}
1126 
1127 	SLOT->dr    = (v & 0x0f) ? 16 + ((v & 0x0f) << 2) : 0;
1128 	SLOT->eg_sh_dr  = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1129 	SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1130 }
1131 
1132 /* set sustain level & release rate */
set_sl_rr(FM_OPL * OPL,int slot,int v)1133 INLINE void set_sl_rr(FM_OPL *OPL, int slot, int v) {
1134 	OPL_CH   *CH   = &OPL->P_CH[slot / 2];
1135 	OPL_SLOT *SLOT = &CH->SLOT[slot & 1];
1136 
1137 	SLOT->sl  = sl_tab[ v >> 4 ];
1138 
1139 	SLOT->rr  = (v & 0x0f) ? 16 + ((v & 0x0f) << 2) : 0;
1140 	SLOT->eg_sh_rr  = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1141 	SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1142 }
1143 
1144 
1145 /* write a value v to register r on OPL chip */
OPLWriteReg(FM_OPL * OPL,int r,int v)1146 void OplClass::OPLWriteReg(FM_OPL *OPL, int r, int v) {
1147 	OPL_CH *CH;
1148 	int slot;
1149 	int block_fnum;
1150 
1151 
1152 	/* adjust bus to 8 bits */
1153 	r &= 0xff;
1154 	v &= 0xff;
1155 
1156 
1157 	switch (r & 0xe0) {
1158 	case 0x00:  /* 00-1f:control */
1159 		switch (r & 0x1f) {
1160 		case 0x01:  /* waveform select enable */
1161 			if (OPL->type & OPL_TYPE_WAVESEL) {
1162 				OPL->wavesel = v & 0x20;
1163 				/* do not change the waveform previously selected */
1164 			}
1165 			break;
1166 		case 0x02:  /* Timer 1 */
1167 			OPL->T[0] = (256 - v) * 4;
1168 			break;
1169 		case 0x03:  /* Timer 2 */
1170 			OPL->T[1] = (256 - v) * 16;
1171 			break;
1172 		case 0x04:  /* IRQ clear / mask and Timer enable */
1173 			if (v & 0x80) {
1174 				/* IRQ flag clear */
1175 				OPL_STATUS_RESET(OPL, 0x7f);
1176 			} else {
1177 				/* set IRQ mask ,timer enable*/
1178 				uint8 st1 = v & 1;
1179 				uint8 st2 = (v >> 1) & 1;
1180 				/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
1181 				OPL_STATUS_RESET(OPL, v & 0x78);
1182 				OPL_STATUSMASK_SET(OPL, ((~v) & 0x78) | 0x01);
1183 				/* timer 2 */
1184 				if (OPL->st[1] != st2) {
1185 					double interval = st2 ? (double)OPL->T[1] * OPL->TimerBase : 0.0;
1186 					OPL->st[1] = st2;
1187 					if (OPL->TimerHandler)(OPL->TimerHandler)(OPL->TimerParam + 1, interval);
1188 				}
1189 				/* timer 1 */
1190 				if (OPL->st[0] != st1) {
1191 					double interval = st1 ? (double)OPL->T[0] * OPL->TimerBase : 0.0;
1192 					OPL->st[0] = st1;
1193 					if (OPL->TimerHandler)(OPL->TimerHandler)(OPL->TimerParam + 0, interval);
1194 				}
1195 			}
1196 			break;
1197 		case 0x08:  /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
1198 			OPL->mode = v;
1199 			break;
1200 
1201 
1202 		}
1203 		break;
1204 	case 0x20:  /* am ON, vib ON, ksr, eg_type, mul */
1205 		slot = slot_array[r & 0x1f];
1206 		if (slot < 0) return;
1207 		set_mul(OPL, slot, v);
1208 		break;
1209 	case 0x40:
1210 		slot = slot_array[r & 0x1f];
1211 		if (slot < 0) return;
1212 		set_ksl_tl(OPL, slot, v);
1213 		break;
1214 	case 0x60:
1215 		slot = slot_array[r & 0x1f];
1216 		if (slot < 0) return;
1217 		set_ar_dr(OPL, slot, v);
1218 		break;
1219 	case 0x80:
1220 		slot = slot_array[r & 0x1f];
1221 		if (slot < 0) return;
1222 		set_sl_rr(OPL, slot, v);
1223 		break;
1224 	case 0xa0:
1225 		if (r == 0xbd) {        /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */
1226 			OPL->lfo_am_depth = v & 0x80;
1227 			OPL->lfo_pm_depth_range = (v & 0x40) ? 8 : 0;
1228 
1229 			OPL->rhythm  = v & 0x3f;
1230 
1231 			if (OPL->rhythm & 0x20) {
1232 				/* BD key on/off */
1233 				if (v & 0x10) {
1234 					FM_KEYON(&OPL->P_CH[6].SLOT[SLOT1], 2U);
1235 					FM_KEYON(&OPL->P_CH[6].SLOT[SLOT2], 2U);
1236 				} else {
1237 					FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1], ~2U);
1238 					FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2], ~2U);
1239 				}
1240 				/* HH key on/off */
1241 				if (v & 0x01) FM_KEYON(&OPL->P_CH[7].SLOT[SLOT1], 2U);
1242 				else       FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1], ~2U);
1243 				/* SD key on/off */
1244 				if (v & 0x08) FM_KEYON(&OPL->P_CH[7].SLOT[SLOT2], 2U);
1245 				else       FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2], ~2U);
1246 				/* TOM key on/off */
1247 				if (v & 0x04) FM_KEYON(&OPL->P_CH[8].SLOT[SLOT1], 2U);
1248 				else       FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1], ~2U);
1249 				/* TOP-CY key on/off */
1250 				if (v & 0x02U) FM_KEYON(&OPL->P_CH[8].SLOT[SLOT2], 2U);
1251 				else       FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2], ~2U);
1252 			} else {
1253 				/* BD key off */
1254 				FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1], ~2U);
1255 				FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2], ~2U);
1256 				/* HH key off */
1257 				FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1], ~2U);
1258 				/* SD key off */
1259 				FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2], ~2U);
1260 				/* TOM key off */
1261 				FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1], ~2U);
1262 				/* TOP-CY off */
1263 				FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2], ~2U);
1264 			}
1265 			return;
1266 		}
1267 		/* keyon,block,fnum */
1268 		if ((r & 0x0f) > 8) return;
1269 		CH = &OPL->P_CH[r & 0x0f];
1270 		if (!(r & 0x10)) {
1271 			/* a0-a8 */
1272 			block_fnum  = (CH->block_fnum & 0x1f00) | v;
1273 		} else {
1274 			/* b0-b8 */
1275 			block_fnum = ((v & 0x1f) << 8) | (CH->block_fnum & 0xff);
1276 
1277 			if (v & 0x20) {
1278 				FM_KEYON(&CH->SLOT[SLOT1], 1U);
1279 				FM_KEYON(&CH->SLOT[SLOT2], 1U);
1280 			} else {
1281 				FM_KEYOFF(&CH->SLOT[SLOT1], ~1U);
1282 				FM_KEYOFF(&CH->SLOT[SLOT2], ~1U);
1283 			}
1284 		}
1285 		/* update */
1286 		if (CH->block_fnum != (uint32)block_fnum) {
1287 			uint8 block  = block_fnum >> 10;
1288 
1289 			CH->block_fnum = block_fnum;
1290 
1291 			CH->ksl_base = ksl_tab[block_fnum >> 6];
1292 			CH->fc       = OPL->fn_tab[block_fnum & 0x03ff] >> (7 - block);
1293 
1294 			/* BLK 2,1,0 bits -> bits 3,2,1 of kcode */
1295 			CH->kcode    = (CH->block_fnum & 0x1c00) >> 9;
1296 
1297 			/* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */
1298 			/* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum  */
1299 			/* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */
1300 			if (OPL->mode & 0x40)
1301 				CH->kcode |= (CH->block_fnum & 0x100) >> 8; /* notesel == 1 */
1302 			else
1303 				CH->kcode |= (CH->block_fnum & 0x200) >> 9; /* notesel == 0 */
1304 
1305 			/* refresh Total Level in both SLOTs of this channel */
1306 			CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base >> CH->SLOT[SLOT1].ksl);
1307 			CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base >> CH->SLOT[SLOT2].ksl);
1308 
1309 			/* refresh frequency counter in both SLOTs of this channel */
1310 			CALC_FCSLOT(CH, &CH->SLOT[SLOT1]);
1311 			CALC_FCSLOT(CH, &CH->SLOT[SLOT2]);
1312 		}
1313 		break;
1314 	case 0xc0:
1315 		/* FB,C */
1316 		if ((r & 0x0f) > 8) return;
1317 		CH = &OPL->P_CH[r & 0x0f];
1318 		CH->SLOT[SLOT1].FB  = (v >> 1) & 7 ? ((v >> 1) & 7) + 7 : 0;
1319 		CH->SLOT[SLOT1].CON = v & 1;
1320 		CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation;
1321 		break;
1322 	case 0xe0: /* waveform select */
1323 		/* simply ignore write to the waveform select register if selecting not enabled in test register */
1324 		if (OPL->wavesel) {
1325 			slot = slot_array[r & 0x1f];
1326 			if (slot < 0) return;
1327 			CH = &OPL->P_CH[slot / 2];
1328 
1329 			CH->SLOT[slot & 1].wavetable = (v & 0x03) * SIN_LEN;
1330 		}
1331 		break;
1332 	}
1333 }
1334 
1335 /* lock/unlock for common table */
OPL_LockTable(void)1336 int OplClass::OPL_LockTable(void) {
1337 	num_lock++;
1338 	if (num_lock > 1) return 0;
1339 
1340 	/* first time */
1341 
1342 	cur_chip = NULL;
1343 	/* allocate total level table (128kb space) */
1344 	if (!init_tables()) {
1345 		num_lock--;
1346 		return -1;
1347 	}
1348 
1349 	return 0;
1350 }
1351 
OPL_UnLockTable(void)1352 void OplClass::OPL_UnLockTable(void) {
1353 	if (num_lock) num_lock--;
1354 	if (num_lock) return;
1355 
1356 	/* last time */
1357 
1358 	cur_chip = NULL;
1359 	OPLCloseTable();
1360 
1361 }
1362 
OPLResetChip(FM_OPL * OPL)1363 void OplClass::OPLResetChip(FM_OPL *OPL) {
1364 	int c, s;
1365 	int i;
1366 
1367 	OPL->eg_timer = 0;
1368 	OPL->eg_cnt   = 0;
1369 
1370 	OPL->noise_rng = 1; /* noise shift register */
1371 	OPL->mode   = 0;    /* normal mode */
1372 	OPL_STATUS_RESET(OPL, 0x7f);
1373 
1374 	/* reset with register write */
1375 	OPLWriteReg(OPL, 0x01, 0); /* wavesel disable */
1376 	OPLWriteReg(OPL, 0x02, 0); /* Timer1 */
1377 	OPLWriteReg(OPL, 0x03, 0); /* Timer2 */
1378 	OPLWriteReg(OPL, 0x04, 0); /* IRQ mask clear */
1379 	for (i = 0xff ; i >= 0x20 ; i--) OPLWriteReg(OPL, i, 0);
1380 
1381 	/* reset operator parameters */
1382 	for (c = 0 ; c < 9 ; c++) {
1383 		OPL_CH *CH = &OPL->P_CH[c];
1384 		for (s = 0 ; s < 2 ; s++) {
1385 			/* wave table */
1386 			CH->SLOT[s].wavetable = 0;
1387 			CH->SLOT[s].state     = EG_OFF;
1388 			CH->SLOT[s].volume    = MAX_ATT_INDEX;
1389 		}
1390 	}
1391 
1392 }
1393 
1394 /* Create one of virtual YM3812 */
1395 /* 'clock' is chip clock in Hz  */
1396 /* 'rate'  is sampling rate  */
OPLCreate(int type,int clock,int rate)1397 FM_OPL *OplClass::OPLCreate(int type, int clock, int rate) {
1398 	char *ptr;
1399 	FM_OPL *OPL;
1400 	int state_size;
1401 
1402 	if (OPL_LockTable() == -1) return NULL;
1403 
1404 	/* calculate OPL state size */
1405 	state_size  = sizeof(FM_OPL);
1406 
1407 	/* allocate memory block */
1408 	ptr = (char *)malloc(state_size);
1409 
1410 	if (ptr == NULL)
1411 		return NULL;
1412 
1413 	/* clear */
1414 	memset(ptr, 0, state_size);
1415 
1416 	OPL  = (FM_OPL *)ptr;
1417 
1418 	ptr += sizeof(FM_OPL);
1419 
1420 	OPL->type  = type;
1421 	OPL->clock = clock;
1422 	OPL->rate  = rate;
1423 
1424 	/* init global tables */
1425 	OPL_initalize(OPL);
1426 
1427 	/* reset chip */
1428 	OPLResetChip(OPL);
1429 	return OPL;
1430 }
1431 
1432 /* Destroy one of virtual YM3812 */
OPLDestroy(FM_OPL * OPL)1433 void OplClass::OPLDestroy(FM_OPL *OPL) {
1434 	OPL_UnLockTable();
1435 	free(OPL);
1436 }
1437 
1438 /* Option handlers */
1439 
OPLSetTimerHandler(FM_OPL * OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)1440 static void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler, int channelOffset) {
1441 	OPL->TimerHandler   = TimerHandler;
1442 	OPL->TimerParam = channelOffset;
1443 }
OPLSetIRQHandler(FM_OPL * OPL,OPL_IRQHANDLER IRQHandler,int param)1444 static void OPLSetIRQHandler(FM_OPL *OPL, OPL_IRQHANDLER IRQHandler, int param) {
1445 	OPL->IRQHandler     = IRQHandler;
1446 	OPL->IRQParam = param;
1447 }
OPLSetUpdateHandler(FM_OPL * OPL,OPL_UPDATEHANDLER UpdateHandler,int param)1448 static void OPLSetUpdateHandler(FM_OPL *OPL, OPL_UPDATEHANDLER UpdateHandler, int param) {
1449 	OPL->UpdateHandler = UpdateHandler;
1450 	OPL->UpdateParam = param;
1451 }
1452 
1453 /* YM3812 I/O interface */
OPLWrite(FM_OPL * OPL,int a,int v)1454 int OplClass::OPLWrite(FM_OPL *OPL, int a, int v) {
1455 	if (!(a & 1)) {
1456 		/* address port */
1457 		OPL->address = v & 0xff;
1458 	} else {
1459 		/* data port */
1460 		if (OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam, 0);
1461 		OPLWriteReg(OPL, OPL->address, v);
1462 	}
1463 	return OPL->status >> 7;
1464 }
1465 
OPLRead(FM_OPL * OPL,int a)1466 static unsigned char OPLRead(FM_OPL *OPL, int a) {
1467 	if (!(a & 1)) {
1468 		/* status port */
1469 		return OPL->status & (OPL->statusmask | 0x80);
1470 	}
1471 
1472 	return 0xff;
1473 }
1474 
1475 /* CSM Key Controll */
CSMKeyControll(OPL_CH * CH)1476 INLINE void CSMKeyControll(OPL_CH *CH) {
1477 	FM_KEYON(&CH->SLOT[SLOT1], 4U);
1478 	FM_KEYON(&CH->SLOT[SLOT2], 4U);
1479 
1480 	/* The key off should happen exactly one sample later - not implemented correctly yet */
1481 
1482 	FM_KEYOFF(&CH->SLOT[SLOT1], ~4U);
1483 	FM_KEYOFF(&CH->SLOT[SLOT2], ~4U);
1484 }
1485 
1486 
OPLTimerOver(FM_OPL * OPL,int c)1487 static int OPLTimerOver(FM_OPL *OPL, int c) {
1488 	if (c) {
1489 		/* Timer B */
1490 		OPL_STATUS_SET(OPL, 0x20);
1491 	} else {
1492 		/* Timer A */
1493 		OPL_STATUS_SET(OPL, 0x40);
1494 		/* CSM mode key,TL controll */
1495 		if (OPL->mode & 0x80) {
1496 			/* CSM mode total level latch and auto key on */
1497 			int ch;
1498 			if (OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam, 0);
1499 			for (ch = 0; ch < 9; ch++)
1500 				CSMKeyControll(&OPL->P_CH[ch]);
1501 		}
1502 	}
1503 	/* reload timer */
1504 	if (OPL->TimerHandler)(OPL->TimerHandler)(OPL->TimerParam + c, (double)OPL->T[c]*OPL->TimerBase);
1505 	return OPL->status >> 7;
1506 }
1507 
1508 #if (BUILD_YM3812)
1509 
1510 
1511 
YM3812Init(int num,int clock,int rate)1512 int OplClass::YM3812Init(int num, int clock, int rate) {
1513 	int i;
1514 
1515 	if (YM3812NumChips)
1516 		return -1;  /* duplicate init. */
1517 
1518 	YM3812NumChips = num;
1519 
1520 	for (i = 0; i < YM3812NumChips; i++) {
1521 		/* emulator create */
1522 		OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812, clock, rate);
1523 		if (OPL_YM3812[i] == NULL) {
1524 			/* it's really bad - we run out of memeory */
1525 			YM3812NumChips = 0;
1526 			return -1;
1527 		}
1528 	}
1529 
1530 	return 0;
1531 }
1532 
YM3812Shutdown(void)1533 void OplClass::YM3812Shutdown(void) {
1534 	int i;
1535 
1536 	for (i = 0; i < YM3812NumChips; i++) {
1537 		/* emulator shutdown */
1538 		OPLDestroy(OPL_YM3812[i]);
1539 		OPL_YM3812[i] = NULL;
1540 	}
1541 	YM3812NumChips = 0;
1542 }
YM3812ResetChip(int which)1543 void OplClass::YM3812ResetChip(int which) {
1544 	OPLResetChip(OPL_YM3812[which]);
1545 }
1546 
YM3812Write(int which,int a,int v)1547 int OplClass::YM3812Write(int which, int a, int v) {
1548 	return OPLWrite(OPL_YM3812[which], a, v);
1549 }
1550 
YM3812Read(int which,int a)1551 unsigned char OplClass::YM3812Read(int which, int a) {
1552 	/* YM3812 always returns bit2 and bit1 in HIGH state */
1553 	return OPLRead(OPL_YM3812[which], a) | 0x06 ;
1554 }
YM3812TimerOver(int which,int c)1555 int OplClass::YM3812TimerOver(int which, int c) {
1556 	return OPLTimerOver(OPL_YM3812[which], c);
1557 }
1558 
YM3812SetTimerHandler(int which,OPL_TIMERHANDLER TimerHandler,int channelOffset)1559 void OplClass::YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) {
1560 	OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset);
1561 }
YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param)1562 void OplClass::YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param) {
1563 	OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param);
1564 }
YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param)1565 void OplClass::YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param) {
1566 	OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param);
1567 }
1568 
1569 
1570 /*
1571 ** Generate samples for one of the YM3812's
1572 **
1573 ** 'which' is the virtual YM3812 number
1574 ** '*buffer' is the output buffer pointer
1575 ** 'length' is the number of samples that should be generated
1576 */
YM3812UpdateOne(int which,int16 * buffer,int length)1577 void OplClass::YM3812UpdateOne(int which, int16 *buffer, int length) {
1578 	FM_OPL      *OPL = OPL_YM3812[which];
1579 	uint8       rhythm = OPL->rhythm & 0x20;
1580 	OPLSAMPLE   *buf = buffer;
1581 	int i;
1582 
1583 	if ((void *)OPL != cur_chip) {
1584 		cur_chip = (void *)OPL;
1585 		/* rhythm slots */
1586 		SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1];
1587 		SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2];
1588 		SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1];
1589 		SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2];
1590 	}
1591 	for (i = 0; i < length ; i++) {
1592 		int lt;
1593 
1594 		output[0] = 0;
1595 
1596 		advance_lfo(OPL);
1597 
1598 		/* FM part */
1599 		OPL_CALC_CH(&OPL->P_CH[0]);
1600 		OPL_CALC_CH(&OPL->P_CH[1]);
1601 		OPL_CALC_CH(&OPL->P_CH[2]);
1602 		OPL_CALC_CH(&OPL->P_CH[3]);
1603 		OPL_CALC_CH(&OPL->P_CH[4]);
1604 		OPL_CALC_CH(&OPL->P_CH[5]);
1605 
1606 		if (!rhythm) {
1607 			OPL_CALC_CH(&OPL->P_CH[6]);
1608 			OPL_CALC_CH(&OPL->P_CH[7]);
1609 			OPL_CALC_CH(&OPL->P_CH[8]);
1610 		} else {    /* Rhythm part */
1611 			OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng >> 0) & 1);
1612 		}
1613 
1614 		lt = output[0];
1615 
1616 		lt >>= FINAL_SH;
1617 
1618 		/* limit check */
1619 		lt = limit(lt , MAXOUT, MINOUT);
1620 
1621 #ifdef SAVE_SAMPLE
1622 		SAVE_ALL_CHANNELS
1623 #endif
1624 
1625 		/* store to sound buffer */
1626 		buf[i] = lt;
1627 
1628 		advancex(OPL);
1629 	}
1630 
1631 }
1632 #endif /* BUILD_YM3812 */
1633 
1634 } // End of namespace Nuvie
1635 } // End of namespace Ultima
1636