initial import
[picodrive.git] / Pico / sound / ym2612.c
1 /*\r
2 ** This is a bunch of remains of original fm.c from MAME project. All stuff \r
3 ** unrelated to ym2612 was removed, multiple chip support was removed,\r
4 ** some parts of code were slightly rewritten and tied to the emulator.\r
5 **\r
6 ** SSG-EG was also removed, because it's rarely used, Sega2.doc even does not\r
7 ** document it ("proprietary") and tells to write 0 to SSG-EG control register.\r
8 */\r
9 \r
10 /*\r
11 **\r
12 ** File: fm.c -- software implementation of Yamaha FM sound generator\r
13 **\r
14 ** Copyright (C) 2001, 2002, 2003 Jarek Burczynski (bujar at mame dot net)\r
15 ** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmulator development\r
16 **\r
17 ** Version 1.4 (final beta)\r
18 **\r
19 */\r
20 \r
21 /*\r
22 ** History:\r
23 **\r
24 ** 03-08-2003 Jarek Burczynski:\r
25 **  - fixed YM2608 initial values (after the reset)\r
26 **  - fixed flag and irqmask handling (YM2608)\r
27 **  - fixed BUFRDY flag handling (YM2608)\r
28 **\r
29 ** 14-06-2003 Jarek Burczynski:\r
30 **  - implemented all of the YM2608 status register flags\r
31 **  - implemented support for external memory read/write via YM2608\r
32 **  - implemented support for deltat memory limit register in YM2608 emulation\r
33 **\r
34 ** 22-05-2003 Jarek Burczynski:\r
35 **  - fixed LFO PM calculations (copy&paste bugfix)\r
36 **\r
37 ** 08-05-2003 Jarek Burczynski:\r
38 **  - fixed SSG support\r
39 **\r
40 ** 22-04-2003 Jarek Burczynski:\r
41 **  - implemented 100% correct LFO generator (verified on real YM2610 and YM2608)\r
42 **\r
43 ** 15-04-2003 Jarek Burczynski:\r
44 **  - added support for YM2608's register 0x110 - status mask\r
45 **\r
46 ** 01-12-2002 Jarek Burczynski:\r
47 **  - fixed register addressing in YM2608, YM2610, YM2610B chips. (verified on real YM2608)\r
48 **    The addressing patch used for early Neo-Geo games can be removed now.\r
49 **\r
50 ** 26-11-2002 Jarek Burczynski, Nicola Salmoria:\r
51 **  - recreated YM2608 ADPCM ROM using data from real YM2608's output which leads to:\r
52 **  - added emulation of YM2608 drums.\r
53 **  - output of YM2608 is two times lower now - same as YM2610 (verified on real YM2608)\r
54 **\r
55 ** 16-08-2002 Jarek Burczynski:\r
56 **  - binary exact Envelope Generator (verified on real YM2203);\r
57 **    identical to YM2151\r
58 **  - corrected 'off by one' error in feedback calculations (when feedback is off)\r
59 **  - corrected connection (algorithm) calculation (verified on real YM2203 and YM2610)\r
60 **\r
61 ** 18-12-2001 Jarek Burczynski:\r
62 **  - added SSG-EG support (verified on real YM2203)\r
63 **\r
64 ** 12-08-2001 Jarek Burczynski:\r
65 **  - corrected ym_sin_tab and ym_tl_tab data (verified on real chip)\r
66 **  - corrected feedback calculations (verified on real chip)\r
67 **  - corrected phase generator calculations (verified on real chip)\r
68 **  - corrected envelope generator calculations (verified on real chip)\r
69 **  - corrected FM volume level (YM2610 and YM2610B).\r
70 **  - changed YMxxxUpdateOne() functions (YM2203, YM2608, YM2610, YM2610B, YM2612) :\r
71 **    this was needed to calculate YM2610 FM channels output correctly.\r
72 **    (Each FM channel is calculated as in other chips, but the output of the channel\r
73 **    gets shifted right by one *before* sending to accumulator. That was impossible to do\r
74 **    with previous implementation).\r
75 **\r
76 ** 23-07-2001 Jarek Burczynski, Nicola Salmoria:\r
77 **  - corrected YM2610 ADPCM type A algorithm and tables (verified on real chip)\r
78 **\r
79 ** 11-06-2001 Jarek Burczynski:\r
80 **  - corrected end of sample bug in ADPCMA_calc_cha().\r
81 **    Real YM2610 checks for equality between current and end addresses (only 20 LSB bits).\r
82 **\r
83 ** 08-12-98 hiro-shi:\r
84 ** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA\r
85 ** move ROM limit check.(CALC_CH? -> 2610Write1/2)\r
86 ** test program (ADPCMB_TEST)\r
87 ** move ADPCM A/B end check.\r
88 ** ADPCMB repeat flag(no check)\r
89 ** change ADPCM volume rate (8->16) (32->48).\r
90 **\r
91 ** 09-12-98 hiro-shi:\r
92 ** change ADPCM volume. (8->16, 48->64)\r
93 ** replace ym2610 ch0/3 (YM-2610B)\r
94 ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.\r
95 ** add ADPCM_SHIFT_MASK\r
96 ** change ADPCMA_DECODE_MIN/MAX.\r
97 */\r
98 \r
99 \r
100 \r
101 \r
102 /************************************************************************/\r
103 /*    comment of hiro-shi(Hiromitsu Shioya)                             */\r
104 /*    YM2610(B) = OPN-B                                                 */\r
105 /*    YM2610  : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */\r
106 /*    YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch      */\r
107 /************************************************************************/\r
108 \r
109 //#include <stdio.h>\r
110 \r
111 #include <string.h>\r
112 #include <math.h>\r
113 \r
114 #include "ym2612.h"\r
115 \r
116 #ifndef EXTERNAL_YM2612\r
117 #include <stdlib.h>\r
118 // let it be 1 global to simplify things\r
119 static YM2612 ym2612;\r
120 \r
121 #else\r
122 extern YM2612 *ym2612_940;\r
123 extern int *mix_buffer;\r
124 #define ym2612 (*ym2612_940)\r
125 \r
126 #endif\r
127 \r
128 \r
129 #ifndef __GNUC__\r
130 #pragma warning (disable:4100) // unreferenced formal parameter\r
131 #pragma warning (disable:4244)\r
132 #pragma warning (disable:4245) // signed/unsigned in conversion\r
133 #pragma warning (disable:4710)\r
134 #pragma warning (disable:4018) // signed/unsigned\r
135 #endif\r
136 \r
137 #ifndef INLINE\r
138 #define INLINE static __inline\r
139 #endif\r
140 \r
141 #ifndef M_PI\r
142 #define M_PI    3.14159265358979323846\r
143 #endif\r
144 \r
145 \r
146 /* globals */\r
147 \r
148 #define FREQ_SH                 16  /* 16.16 fixed point (frequency calculations) */\r
149 #define EG_SH                   16  /* 16.16 fixed point (envelope generator timing) */\r
150 #define LFO_SH                  25  /*  7.25 fixed point (LFO calculations)       */\r
151 #define TIMER_SH                16  /* 16.16 fixed point (timers calculations)    */\r
152 \r
153 #define ENV_BITS                10\r
154 #define ENV_LEN                 (1<<ENV_BITS)\r
155 #define ENV_STEP                (128.0/ENV_LEN)\r
156 \r
157 #define MAX_ATT_INDEX   (ENV_LEN-1) /* 1023 */\r
158 #define MIN_ATT_INDEX   (0)                     /* 0 */\r
159 \r
160 #define EG_ATT                  4\r
161 #define EG_DEC                  3\r
162 #define EG_SUS                  2\r
163 #define EG_REL                  1\r
164 #define EG_OFF                  0\r
165 \r
166 #define SIN_BITS                10\r
167 #define SIN_LEN                 (1<<SIN_BITS)\r
168 #define SIN_MASK                (SIN_LEN-1)\r
169 \r
170 #define TL_RES_LEN              (256) /* 8 bits addressing (real chip) */\r
171 \r
172 #define EG_TIMER_OVERFLOW (3*(1<<EG_SH)) /* envelope generator timer overflows every 3 samples (on real chip) */\r
173 \r
174 #define MAXOUT          (+32767)\r
175 #define MINOUT          (-32768)\r
176 \r
177 /* limitter */\r
178 #define Limit(val, max,min) { \\r
179         if ( val > max )      val = max; \\r
180         else if ( val < min ) val = min; \\r
181 }\r
182 \r
183 \r
184 /*  TL_TAB_LEN is calculated as:\r
185 *   13 - sinus amplitude bits     (Y axis)\r
186 *   2  - sinus sign bit           (Y axis)\r
187 *   TL_RES_LEN - sinus resolution (X axis)\r
188 */\r
189 //#define TL_TAB_LEN (13*2*TL_RES_LEN)\r
190 #define TL_TAB_LEN (13*TL_RES_LEN*256/8) // 106496*2\r
191 UINT16 ym_tl_tab[TL_TAB_LEN];\r
192 \r
193 /* ~3K wasted but oh well */\r
194 UINT16 ym_tl_tab2[13*TL_RES_LEN];\r
195 \r
196 #define ENV_QUIET               (2*13*TL_RES_LEN/8)\r
197 \r
198 /* sin waveform table in 'decibel' scale (use only period/4 values) */\r
199 static UINT16 ym_sin_tab[256];\r
200 \r
201 /* sustain level table (3dB per step) */\r
202 /* bit0, bit1, bit2, bit3, bit4, bit5, bit6 */\r
203 /* 1,    2,    4,    8,    16,   32,   64   (value)*/\r
204 /* 0.75, 1.5,  3,    6,    12,   24,   48   (dB)*/\r
205 \r
206 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/\r
207 #define SC(db) (UINT32) ( db * (4.0/ENV_STEP) )\r
208 static const UINT32 sl_table[16]={\r
209  SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),\r
210  SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)\r
211 };\r
212 #undef SC\r
213 \r
214 \r
215 #if 0\r
216 #define RATE_STEPS (8)\r
217 static const UINT8 eg_inc[19*RATE_STEPS]={\r
218 \r
219 /*cycle:0 1  2 3  4 5  6 7*/\r
220 \r
221 /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..11 0 (increment by 0 or 1) */\r
222 /* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..11 1 */\r
223 /* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..11 2 */\r
224 /* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..11 3 */\r
225 \r
226 /* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 12 0 (increment by 1) */\r
227 /* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 12 1 */\r
228 /* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 12 2 */\r
229 /* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 12 3 */\r
230 \r
231 /* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 13 0 (increment by 2) */\r
232 /* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 13 1 */\r
233 /*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 13 2 */\r
234 /*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 13 3 */\r
235 \r
236 /*12 */ 4,4, 4,4, 4,4, 4,4, /* rate 14 0 (increment by 4) */\r
237 /*13 */ 4,4, 4,8, 4,4, 4,8, /* rate 14 1 */\r
238 /*14 */ 4,8, 4,8, 4,8, 4,8, /* rate 14 2 */\r
239 /*15 */ 4,8, 8,8, 4,8, 8,8, /* rate 14 3 */\r
240 \r
241 /*16 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */\r
242 /*17 */ 16,16,16,16,16,16,16,16, /* rates 15 2, 15 3 for attack */\r
243 /*18 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */\r
244 };\r
245 #endif\r
246 \r
247 \r
248 #define PACK(a0,a1,a2,a3,a4,a5,a6,a7) ((a7<<21)|(a6<<18)|(a5<<15)|(a4<<12)|(a3<<9)|(a2<<6)|(a1<<3)|(a0<<0))\r
249 static const UINT32 eg_inc_pack[19] =\r
250 {\r
251 /* 0 */ PACK(0,1,0,1,0,1,0,1), /* rates 00..11 0 (increment by 0 or 1) */\r
252 /* 1 */ PACK(0,1,0,1,1,1,0,1), /* rates 00..11 1 */\r
253 /* 2 */ PACK(0,1,1,1,0,1,1,1), /* rates 00..11 2 */\r
254 /* 3 */ PACK(0,1,1,1,1,1,1,1), /* rates 00..11 3 */\r
255 \r
256 /* 4 */ PACK(1,1,1,1,1,1,1,1), /* rate 12 0 (increment by 1) */\r
257 /* 5 */ PACK(1,1,1,2,1,1,1,2), /* rate 12 1 */\r
258 /* 6 */ PACK(1,2,1,2,1,2,1,2), /* rate 12 2 */\r
259 /* 7 */ PACK(1,2,2,2,1,2,2,2), /* rate 12 3 */\r
260 \r
261 /* 8 */ PACK(2,2,2,2,2,2,2,2), /* rate 13 0 (increment by 2) */\r
262 /* 9 */ PACK(2,2,2,3,2,2,2,3), /* rate 13 1 */\r
263 /*10 */ PACK(2,3,2,3,2,3,2,3), /* rate 13 2 */\r
264 /*11 */ PACK(2,3,3,3,2,3,3,3), /* rate 13 3 */\r
265 \r
266 /*12 */ PACK(3,3,3,3,3,3,3,3), /* rate 14 0 (increment by 4) */\r
267 /*13 */ PACK(3,3,3,4,3,3,3,4), /* rate 14 1 */\r
268 /*14 */ PACK(3,4,3,4,3,4,3,4), /* rate 14 2 */\r
269 /*15 */ PACK(3,4,4,4,3,4,4,4), /* rate 14 3 */\r
270 \r
271 /*16 */ PACK(4,4,4,4,4,4,4,4), /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */\r
272 /*17 */ PACK(5,5,5,5,5,5,5,5), /* rates 15 2, 15 3 for attack */\r
273 /*18 */ PACK(0,0,0,0,0,0,0,0), /* infinity rates for attack and decay(s) */\r
274 };\r
275 \r
276 \r
277 //#define O(a) (a*RATE_STEPS)\r
278 #define O(a) a\r
279 \r
280 /*note that there is no O(17) in this table - it's directly in the code */\r
281 static const UINT8 eg_rate_select[32+64+32]={   /* Envelope Generator rates (32 + 64 rates + 32 RKS) */\r
282 /* 32 infinite time rates */\r
283 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),\r
284 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),\r
285 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),\r
286 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),\r
287 \r
288 /* rates 00-11 */\r
289 O( 0),O( 1),O( 2),O( 3),\r
290 O( 0),O( 1),O( 2),O( 3),\r
291 O( 0),O( 1),O( 2),O( 3),\r
292 O( 0),O( 1),O( 2),O( 3),\r
293 O( 0),O( 1),O( 2),O( 3),\r
294 O( 0),O( 1),O( 2),O( 3),\r
295 O( 0),O( 1),O( 2),O( 3),\r
296 O( 0),O( 1),O( 2),O( 3),\r
297 O( 0),O( 1),O( 2),O( 3),\r
298 O( 0),O( 1),O( 2),O( 3),\r
299 O( 0),O( 1),O( 2),O( 3),\r
300 O( 0),O( 1),O( 2),O( 3),\r
301 \r
302 /* rate 12 */\r
303 O( 4),O( 5),O( 6),O( 7),\r
304 \r
305 /* rate 13 */\r
306 O( 8),O( 9),O(10),O(11),\r
307 \r
308 /* rate 14 */\r
309 O(12),O(13),O(14),O(15),\r
310 \r
311 /* rate 15 */\r
312 O(16),O(16),O(16),O(16),\r
313 \r
314 /* 32 dummy rates (same as 15 3) */\r
315 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),\r
316 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),\r
317 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),\r
318 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)\r
319 \r
320 };\r
321 #undef O\r
322 \r
323 /*rate  0,    1,    2,   3,   4,   5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15*/\r
324 /*shift 11,   10,   9,   8,   7,   6,  5,  4,  3,  2, 1,  0,  0,  0,  0,  0 */\r
325 /*mask  2047, 1023, 511, 255, 127, 63, 31, 15, 7,  3, 1,  0,  0,  0,  0,  0 */\r
326 \r
327 #define O(a) (a*1)\r
328 static const UINT8 eg_rate_shift[32+64+32]={    /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */\r
329 /* 32 infinite time rates */\r
330 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
331 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
332 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
333 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
334 \r
335 /* rates 00-11 */\r
336 O(11),O(11),O(11),O(11),\r
337 O(10),O(10),O(10),O(10),\r
338 O( 9),O( 9),O( 9),O( 9),\r
339 O( 8),O( 8),O( 8),O( 8),\r
340 O( 7),O( 7),O( 7),O( 7),\r
341 O( 6),O( 6),O( 6),O( 6),\r
342 O( 5),O( 5),O( 5),O( 5),\r
343 O( 4),O( 4),O( 4),O( 4),\r
344 O( 3),O( 3),O( 3),O( 3),\r
345 O( 2),O( 2),O( 2),O( 2),\r
346 O( 1),O( 1),O( 1),O( 1),\r
347 O( 0),O( 0),O( 0),O( 0),\r
348 \r
349 /* rate 12 */\r
350 O( 0),O( 0),O( 0),O( 0),\r
351 \r
352 /* rate 13 */\r
353 O( 0),O( 0),O( 0),O( 0),\r
354 \r
355 /* rate 14 */\r
356 O( 0),O( 0),O( 0),O( 0),\r
357 \r
358 /* rate 15 */\r
359 O( 0),O( 0),O( 0),O( 0),\r
360 \r
361 /* 32 dummy rates (same as 15 3) */\r
362 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),\r
363 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),\r
364 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),\r
365 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0)\r
366 \r
367 };\r
368 #undef O\r
369 \r
370 static const UINT8 dt_tab[4 * 32]={\r
371 /* this is YM2151 and YM2612 phase increment data (in 10.10 fixed point format)*/\r
372 /* FD=0 */\r
373         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
374         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r
375 /* FD=1 */\r
376         0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,\r
377         2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,\r
378 /* FD=2 */\r
379         1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,\r
380         5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,\r
381 /* FD=3 */\r
382         2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,\r
383         8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22\r
384 };\r
385 \r
386 \r
387 /* OPN key frequency number -> key code follow table */\r
388 /* fnum higher 4bit -> keycode lower 2bit */\r
389 static const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};\r
390 \r
391 \r
392 /* 8 LFO speed parameters */\r
393 /* each value represents number of samples that one LFO level will last for */\r
394 static const UINT32 lfo_samples_per_step[8] = {108, 77, 71, 67, 62, 44, 8, 5};\r
395 \r
396 \r
397 \r
398 /*There are 4 different LFO AM depths available, they are:\r
399   0 dB, 1.4 dB, 5.9 dB, 11.8 dB\r
400   Here is how it is generated (in EG steps):\r
401 \r
402   11.8 dB = 0, 2, 4, 6, 8, 10,12,14,16...126,126,124,122,120,118,....4,2,0\r
403    5.9 dB = 0, 1, 2, 3, 4, 5, 6, 7, 8....63, 63, 62, 61, 60, 59,.....2,1,0\r
404    1.4 dB = 0, 0, 0, 0, 1, 1, 1, 1, 2,...15, 15, 15, 15, 14, 14,.....0,0,0\r
405 \r
406   (1.4 dB is loosing precision as you can see)\r
407 \r
408   It's implemented as generator from 0..126 with step 2 then a shift\r
409   right N times, where N is:\r
410     8 for 0 dB\r
411     3 for 1.4 dB\r
412     1 for 5.9 dB\r
413     0 for 11.8 dB\r
414 */\r
415 static const UINT8 lfo_ams_depth_shift[4] = {8, 3, 1, 0};\r
416 \r
417 \r
418 \r
419 /*There are 8 different LFO PM depths available, they are:\r
420   0, 3.4, 6.7, 10, 14, 20, 40, 80 (cents)\r
421 \r
422   Modulation level at each depth depends on F-NUMBER bits: 4,5,6,7,8,9,10\r
423   (bits 8,9,10 = FNUM MSB from OCT/FNUM register)\r
424 \r
425   Here we store only first quarter (positive one) of full waveform.\r
426   Full table (lfo_pm_table) containing all 128 waveforms is build\r
427   at run (init) time.\r
428 \r
429   One value in table below represents 4 (four) basic LFO steps\r
430   (1 PM step = 4 AM steps).\r
431 \r
432   For example:\r
433    at LFO SPEED=0 (which is 108 samples per basic LFO step)\r
434    one value from "lfo_pm_output" table lasts for 432 consecutive\r
435    samples (4*108=432) and one full LFO waveform cycle lasts for 13824\r
436    samples (32*432=13824; 32 because we store only a quarter of whole\r
437             waveform in the table below)\r
438 */\r
439 static const UINT8 lfo_pm_output[7*8][8]={ /* 7 bits meaningful (of F-NUMBER), 8 LFO output levels per one depth (out of 32), 8 LFO depths */\r
440 /* FNUM BIT 4: 000 0001xxxx */\r
441 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
442 /* DEPTH 1 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
443 /* DEPTH 2 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
444 /* DEPTH 3 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
445 /* DEPTH 4 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
446 /* DEPTH 5 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
447 /* DEPTH 6 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
448 /* DEPTH 7 */ {0,   0,   0,   0,   1,   1,   1,   1},\r
449 \r
450 /* FNUM BIT 5: 000 0010xxxx */\r
451 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
452 /* DEPTH 1 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
453 /* DEPTH 2 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
454 /* DEPTH 3 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
455 /* DEPTH 4 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
456 /* DEPTH 5 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
457 /* DEPTH 6 */ {0,   0,   0,   0,   1,   1,   1,   1},\r
458 /* DEPTH 7 */ {0,   0,   1,   1,   2,   2,   2,   3},\r
459 \r
460 /* FNUM BIT 6: 000 0100xxxx */\r
461 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
462 /* DEPTH 1 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
463 /* DEPTH 2 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
464 /* DEPTH 3 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
465 /* DEPTH 4 */ {0,   0,   0,   0,   0,   0,   0,   1},\r
466 /* DEPTH 5 */ {0,   0,   0,   0,   1,   1,   1,   1},\r
467 /* DEPTH 6 */ {0,   0,   1,   1,   2,   2,   2,   3},\r
468 /* DEPTH 7 */ {0,   0,   2,   3,   4,   4,   5,   6},\r
469 \r
470 /* FNUM BIT 7: 000 1000xxxx */\r
471 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
472 /* DEPTH 1 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
473 /* DEPTH 2 */ {0,   0,   0,   0,   0,   0,   1,   1},\r
474 /* DEPTH 3 */ {0,   0,   0,   0,   1,   1,   1,   1},\r
475 /* DEPTH 4 */ {0,   0,   0,   1,   1,   1,   1,   2},\r
476 /* DEPTH 5 */ {0,   0,   1,   1,   2,   2,   2,   3},\r
477 /* DEPTH 6 */ {0,   0,   2,   3,   4,   4,   5,   6},\r
478 /* DEPTH 7 */ {0,   0,   4,   6,   8,   8, 0xa, 0xc},\r
479 \r
480 /* FNUM BIT 8: 001 0000xxxx */\r
481 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
482 /* DEPTH 1 */ {0,   0,   0,   0,   1,   1,   1,   1},\r
483 /* DEPTH 2 */ {0,   0,   0,   1,   1,   1,   2,   2},\r
484 /* DEPTH 3 */ {0,   0,   1,   1,   2,   2,   3,   3},\r
485 /* DEPTH 4 */ {0,   0,   1,   2,   2,   2,   3,   4},\r
486 /* DEPTH 5 */ {0,   0,   2,   3,   4,   4,   5,   6},\r
487 /* DEPTH 6 */ {0,   0,   4,   6,   8,   8, 0xa, 0xc},\r
488 /* DEPTH 7 */ {0,   0,   8, 0xc,0x10,0x10,0x14,0x18},\r
489 \r
490 /* FNUM BIT 9: 010 0000xxxx */\r
491 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
492 /* DEPTH 1 */ {0,   0,   0,   0,   2,   2,   2,   2},\r
493 /* DEPTH 2 */ {0,   0,   0,   2,   2,   2,   4,   4},\r
494 /* DEPTH 3 */ {0,   0,   2,   2,   4,   4,   6,   6},\r
495 /* DEPTH 4 */ {0,   0,   2,   4,   4,   4,   6,   8},\r
496 /* DEPTH 5 */ {0,   0,   4,   6,   8,   8, 0xa, 0xc},\r
497 /* DEPTH 6 */ {0,   0,   8, 0xc,0x10,0x10,0x14,0x18},\r
498 /* DEPTH 7 */ {0,   0,0x10,0x18,0x20,0x20,0x28,0x30},\r
499 \r
500 /* FNUM BIT10: 100 0000xxxx */\r
501 /* DEPTH 0 */ {0,   0,   0,   0,   0,   0,   0,   0},\r
502 /* DEPTH 1 */ {0,   0,   0,   0,   4,   4,   4,   4},\r
503 /* DEPTH 2 */ {0,   0,   0,   4,   4,   4,   8,   8},\r
504 /* DEPTH 3 */ {0,   0,   4,   4,   8,   8, 0xc, 0xc},\r
505 /* DEPTH 4 */ {0,   0,   4,   8,   8,   8, 0xc,0x10},\r
506 /* DEPTH 5 */ {0,   0,   8, 0xc,0x10,0x10,0x14,0x18},\r
507 /* DEPTH 6 */ {0,   0,0x10,0x18,0x20,0x20,0x28,0x30},\r
508 /* DEPTH 7 */ {0,   0,0x20,0x30,0x40,0x40,0x50,0x60},\r
509 \r
510 };\r
511 \r
512 /* all 128 LFO PM waveforms */\r
513 static INT32 lfo_pm_table[128*8*32]; /* 128 combinations of 7 bits meaningful (of F-NUMBER), 8 LFO depths, 32 LFO output levels per one depth */\r
514 \r
515 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers\r
516         but LFO works with one more bit of a precision so we really need 4096 elements */\r
517 static UINT32 fn_table[4096];   /* fnumber->increment counter */\r
518 \r
519 static int g_lfo_ampm = 0;\r
520 \r
521 /* register number to channel number , slot offset */\r
522 #define OPN_CHAN(N) (N&3)\r
523 #define OPN_SLOT(N) ((N>>2)&3)\r
524 \r
525 /* slot number */\r
526 #define SLOT1 0\r
527 #define SLOT2 2\r
528 #define SLOT3 1\r
529 #define SLOT4 3\r
530 \r
531 \r
532 /* OPN Mode Register Write */\r
533 INLINE void set_timers( int v )\r
534 {\r
535         /* b7 = CSM MODE */\r
536         /* b6 = 3 slot mode */\r
537         /* b5 = reset b */\r
538         /* b4 = reset a */\r
539         /* b3 = timer enable b */\r
540         /* b2 = timer enable a */\r
541         /* b1 = load b */\r
542         /* b0 = load a */\r
543         ym2612.OPN.ST.mode = v;\r
544 \r
545         /* reset Timer b flag */\r
546         if( v & 0x20 )\r
547                 ym2612.OPN.ST.status &= ~2;\r
548 \r
549         /* reset Timer a flag */\r
550         if( v & 0x10 )\r
551                 ym2612.OPN.ST.status &= ~1;\r
552 }\r
553 \r
554 \r
555 INLINE void FM_KEYON(FM_CH *CH , int s )\r
556 {\r
557         FM_SLOT *SLOT = &CH->SLOT[s];\r
558         if( !SLOT->key )\r
559         {\r
560                 SLOT->key = 1;\r
561                 SLOT->phase = 0;                /* restart Phase Generator */\r
562                 SLOT->state = EG_ATT;   /* phase -> Attack */\r
563         }\r
564 }\r
565 \r
566 INLINE void FM_KEYOFF(FM_CH *CH , int s )\r
567 {\r
568         FM_SLOT *SLOT = &CH->SLOT[s];\r
569         if( SLOT->key )\r
570         {\r
571                 SLOT->key = 0;\r
572                 if (SLOT->state>EG_REL)\r
573                         SLOT->state = EG_REL;/* phase -> Release */\r
574         }\r
575 }\r
576 \r
577 \r
578 /* set detune & multiple */\r
579 INLINE void set_det_mul(FM_CH *CH, FM_SLOT *SLOT, int v)\r
580 {\r
581         SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1;\r
582         SLOT->DT  = ym2612.OPN.ST.dt_tab[(v>>4)&7];\r
583         CH->SLOT[SLOT1].Incr=-1;\r
584 }\r
585 \r
586 /* set total level */\r
587 INLINE void set_tl(FM_SLOT *SLOT, int v)\r
588 {\r
589         SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */\r
590 }\r
591 \r
592 /* set attack rate & key scale  */\r
593 INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)\r
594 {\r
595         UINT8 old_KSR = SLOT->KSR;\r
596 \r
597         SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
598 \r
599         SLOT->KSR = 3-(v>>6);\r
600         if (SLOT->KSR != old_KSR)\r
601         {\r
602                 CH->SLOT[SLOT1].Incr=-1;\r
603         }\r
604         else\r
605         {\r
606                 int eg_sh_ar, eg_sel_ar;\r
607 \r
608                 /* refresh Attack rate */\r
609                 if ((SLOT->ar + SLOT->ksr) < 32+62)\r
610                 {\r
611                         eg_sh_ar  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];\r
612                         eg_sel_ar = eg_rate_select[SLOT->ar  + SLOT->ksr ];\r
613                 }\r
614                 else\r
615                 {\r
616                         eg_sh_ar  = 0;\r
617                         eg_sel_ar = 17;\r
618                 }\r
619 \r
620                 SLOT->eg_pack_ar = eg_inc_pack[eg_sel_ar] | (eg_sh_ar<<24);\r
621         }\r
622 }\r
623 \r
624 /* set decay rate */\r
625 INLINE void set_dr(FM_SLOT *SLOT, int v)\r
626 {\r
627         int eg_sh_d1r, eg_sel_d1r;\r
628 \r
629         SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
630 \r
631         eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];\r
632         eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];\r
633 \r
634         SLOT->eg_pack_d1r = eg_inc_pack[eg_sel_d1r] | (eg_sh_d1r<<24);\r
635 }\r
636 \r
637 /* set sustain rate */\r
638 INLINE void set_sr(FM_SLOT *SLOT, int v)\r
639 {\r
640         int eg_sh_d2r, eg_sel_d2r;\r
641 \r
642         SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
643 \r
644         eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];\r
645         eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];\r
646 \r
647         SLOT->eg_pack_d2r = eg_inc_pack[eg_sel_d2r] | (eg_sh_d2r<<24);\r
648 }\r
649 \r
650 /* set release rate */\r
651 INLINE void set_sl_rr(FM_SLOT *SLOT, int v)\r
652 {\r
653         int eg_sh_rr, eg_sel_rr;\r
654 \r
655         SLOT->sl = sl_table[ v>>4 ];\r
656 \r
657         SLOT->rr  = 34 + ((v&0x0f)<<2);\r
658 \r
659         eg_sh_rr  = eg_rate_shift [SLOT->rr  + SLOT->ksr];\r
660         eg_sel_rr = eg_rate_select[SLOT->rr  + SLOT->ksr];\r
661 \r
662         SLOT->eg_pack_rr = eg_inc_pack[eg_sel_rr] | (eg_sh_rr<<24);\r
663 }\r
664 \r
665 \r
666 \r
667 INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm)\r
668 {\r
669         int ret, sin = (phase>>16) + (pm>>1);\r
670         int neg = sin & 0x200;\r
671         if (sin & 0x100) sin ^= 0xff;\r
672         sin&=0xff;\r
673         env&=~1;\r
674 \r
675         // this was already checked\r
676         // if (env >= ENV_QUIET) // 384\r
677         //      return 0;\r
678 \r
679         ret = ym_tl_tab[sin | (env<<7)];\r
680 \r
681         return neg ? -ret : ret;\r
682 }\r
683 \r
684 INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm)\r
685 {\r
686         int ret, sin = (phase+pm)>>16;\r
687         int neg = sin & 0x200;\r
688         if (sin & 0x100) sin ^= 0xff;\r
689         sin&=0xff;\r
690         env&=~1;\r
691 \r
692         // if (env >= ENV_QUIET) // 384\r
693         //      return 0;\r
694 \r
695         ret = ym_tl_tab[sin | (env<<7)];\r
696 \r
697         return neg ? -ret : ret;\r
698 }\r
699 \r
700 #if !defined(_ASM_YM2612_C) || defined(EXTERNAL_YM2612)\r
701 /* advance LFO to next sample */\r
702 INLINE int advance_lfo(int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt)\r
703 {\r
704         UINT8 pos;\r
705         UINT8 prev_pos;\r
706 \r
707         prev_pos = (lfo_cnt_old >> LFO_SH) & 127;\r
708 \r
709         pos = (lfo_cnt >> LFO_SH) & 127;\r
710 \r
711         /* update AM when LFO output changes */\r
712 \r
713         if (prev_pos != pos)\r
714         {\r
715                 lfo_ampm &= 0xff;\r
716                 /* triangle */\r
717                 /* AM: 0 to 126 step +2, 126 to 0 step -2 */\r
718                 if (pos<64)\r
719                         lfo_ampm |= ((pos&63) * 2) << 8;           /* 0 - 126 */\r
720                 else\r
721                         lfo_ampm |= (126 - (pos&63)*2) << 8;\r
722         }\r
723         else\r
724         {\r
725                 return lfo_ampm;\r
726         }\r
727 \r
728         /* PM works with 4 times slower clock */\r
729         prev_pos >>= 2;\r
730         pos >>= 2;\r
731         /* update PM when LFO output changes */\r
732         if (prev_pos != pos)\r
733         {\r
734                 lfo_ampm &= ~0xff;\r
735                 lfo_ampm |= pos; /* 0 - 32 */\r
736         }\r
737         return lfo_ampm;\r
738 }\r
739 \r
740 #define EG_INC_VAL() \\r
741         ((1 << ((pack >> ((eg_cnt>>shift)&7)*3)&7)) >> 1)\r
742 \r
743 INLINE UINT32 update_eg_phase(FM_SLOT *SLOT, UINT32 eg_cnt)\r
744 {\r
745         INT32 volume = SLOT->volume;\r
746 \r
747         switch(SLOT->state)\r
748         {\r
749                 case EG_ATT:            /* attack phase */\r
750                 {\r
751                         UINT32 pack = SLOT->eg_pack_ar;\r
752                         UINT32 shift = pack>>24;\r
753                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
754                         {\r
755                                 volume += ( ~volume * EG_INC_VAL() ) >>4;\r
756 \r
757                                 if (volume <= MIN_ATT_INDEX)\r
758                                 {\r
759                                         volume = MIN_ATT_INDEX;\r
760                                         SLOT->state = EG_DEC;\r
761                                 }\r
762                         }\r
763                         break;\r
764                 }\r
765 \r
766                 case EG_DEC:    /* decay phase */\r
767                 {\r
768                         UINT32 pack = SLOT->eg_pack_d1r;\r
769                         UINT32 shift = pack>>24;\r
770                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
771                         {\r
772                                 volume += EG_INC_VAL();\r
773 \r
774                                 if ( volume >= (INT32) SLOT->sl )\r
775                                         SLOT->state = EG_SUS;\r
776                         }\r
777                         break;\r
778                 }\r
779 \r
780                 case EG_SUS:    /* sustain phase */\r
781                 {\r
782                         UINT32 pack = SLOT->eg_pack_d2r;\r
783                         UINT32 shift = pack>>24;\r
784                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
785                         {\r
786                                 volume += EG_INC_VAL();\r
787 \r
788                                 if ( volume >= MAX_ATT_INDEX )\r
789                                 {\r
790                                         volume = MAX_ATT_INDEX;\r
791                                         /* do not change SLOT->state (verified on real chip) */\r
792                                 }\r
793                         }\r
794                         break;\r
795                 }\r
796 \r
797                 case EG_REL:    /* release phase */\r
798                 {\r
799                         UINT32 pack = SLOT->eg_pack_rr;\r
800                         UINT32 shift = pack>>24;\r
801                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
802                         {\r
803                                 volume += EG_INC_VAL();\r
804 \r
805                                 if ( volume >= MAX_ATT_INDEX )\r
806                                 {\r
807                                         volume = MAX_ATT_INDEX;\r
808                                         SLOT->state = EG_OFF;\r
809                                 }\r
810                         }\r
811                         break;\r
812                 }\r
813         }\r
814 \r
815         SLOT->volume = volume;\r
816         return SLOT->tl + ((UINT32)volume); /* tl is 7bit<<3, volume 0-1023 (0-2039 total) */\r
817 }\r
818 #endif\r
819 \r
820 \r
821 typedef struct\r
822 {\r
823         UINT16 vol_out1; /* 00: current output from EG circuit (without AM from LFO) */\r
824         UINT16 vol_out2;\r
825         UINT16 vol_out3;\r
826         UINT16 vol_out4;\r
827         UINT32 pad[2];\r
828         UINT32 phase1;   /* 10 */\r
829         UINT32 phase2;\r
830         UINT32 phase3;\r
831         UINT32 phase4;\r
832         UINT32 incr1;    /* 20: phase step */\r
833         UINT32 incr2;\r
834         UINT32 incr3;\r
835         UINT32 incr4;\r
836         UINT32 lfo_cnt;  /* 30 */\r
837         UINT32 lfo_inc;\r
838         INT32  mem;      /* one sample delay memory */\r
839         UINT32 eg_cnt;   /* envelope generator counter */\r
840         FM_CH  *CH;      /* 40: envelope generator counter */\r
841         UINT32 eg_timer;\r
842         UINT32 eg_timer_add;\r
843         UINT32 pack;     // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16]\r
844         UINT32 algo;     /* 50 */\r
845         INT32  op1_out;\r
846 } chan_rend_context;\r
847 \r
848 \r
849 #if !defined(_ASM_YM2612_C) || defined(EXTERNAL_YM2612)\r
850 static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)\r
851 {\r
852         int scounter;                                   /* sample counter */\r
853 \r
854         /* sample generating loop */\r
855         for (scounter = 0; scounter < length; scounter++)\r
856         {\r
857                 int smp = 0;            /* produced sample */\r
858                 unsigned int eg_out, eg_out2, eg_out4;\r
859 \r
860                 if (ct->pack & 8) { /* LFO enabled ? (test Earthworm Jim in between demo 1 and 2) */\r
861                         ct->pack = (ct->pack&0xffff) | (advance_lfo(ct->pack >> 16, ct->lfo_cnt, ct->lfo_cnt + ct->lfo_inc) << 16);\r
862                         ct->lfo_cnt += ct->lfo_inc;\r
863                 }\r
864 \r
865                 ct->eg_timer += ct->eg_timer_add;\r
866                 while (ct->eg_timer >= EG_TIMER_OVERFLOW)\r
867                 {\r
868                         ct->eg_timer -= EG_TIMER_OVERFLOW;\r
869                         ct->eg_cnt++;\r
870 \r
871                         if (ct->CH->SLOT[SLOT1].state != EG_OFF) ct->vol_out1 = update_eg_phase(&ct->CH->SLOT[SLOT1], ct->eg_cnt);\r
872                         if (ct->CH->SLOT[SLOT2].state != EG_OFF) ct->vol_out2 = update_eg_phase(&ct->CH->SLOT[SLOT2], ct->eg_cnt);\r
873                         if (ct->CH->SLOT[SLOT3].state != EG_OFF) ct->vol_out3 = update_eg_phase(&ct->CH->SLOT[SLOT3], ct->eg_cnt);\r
874                         if (ct->CH->SLOT[SLOT4].state != EG_OFF) ct->vol_out4 = update_eg_phase(&ct->CH->SLOT[SLOT4], ct->eg_cnt);\r
875                 }\r
876 \r
877                 if (ct->pack & 4) continue; /* output disabled */\r
878 \r
879                 /* calculate channel sample */\r
880                 eg_out = ct->vol_out1;\r
881                 if ( (ct->pack & 8) && (ct->pack&(1<<(SLOT1+8))) ) eg_out += ct->pack >> (((ct->pack&0xc0)>>6)+24);\r
882 \r
883                 if( eg_out < ENV_QUIET )        /* SLOT 1 */\r
884                 {\r
885                         int out = 0;\r
886 \r
887                         if (ct->pack&0xf000) out = ((ct->op1_out>>16) + (ct->op1_out<<16>>16)) << ((ct->pack&0xf000)>>12); /* op1_out0 + op1_out1 */\r
888                         ct->op1_out <<= 16;\r
889                         ct->op1_out |= (unsigned short)op_calc1(ct->phase1, eg_out, out);\r
890                 } else {\r
891                         ct->op1_out <<= 16; /* op1_out0 = op1_out1; op1_out1 = 0; */\r
892                 }\r
893 \r
894                 eg_out  = ct->vol_out3; // volume_calc(&CH->SLOT[SLOT3]);\r
895                 eg_out2 = ct->vol_out2; // volume_calc(&CH->SLOT[SLOT2]);\r
896                 eg_out4 = ct->vol_out4; // volume_calc(&CH->SLOT[SLOT4]);\r
897 \r
898                 if (ct->pack & 8) {\r
899                         unsigned int add = ct->pack >> (((ct->pack&0xc0)>>6)+24);\r
900                         if (ct->pack & (1<<(SLOT3+8))) eg_out  += add;\r
901                         if (ct->pack & (1<<(SLOT2+8))) eg_out2 += add;\r
902                         if (ct->pack & (1<<(SLOT4+8))) eg_out4 += add;\r
903                 }\r
904 \r
905                 switch( ct->CH->ALGO )\r
906                 {\r
907 #if 0\r
908                         case 0: smp = upd_algo0(ct); break;\r
909                         case 1: smp = upd_algo1(ct); break;\r
910                         case 2: smp = upd_algo2(ct); break;\r
911                         case 3: smp = upd_algo3(ct); break;\r
912                         case 4: smp = upd_algo4(ct); break;\r
913                         case 5: smp = upd_algo5(ct); break;\r
914                         case 6: smp = upd_algo6(ct); break;\r
915                         case 7: smp = upd_algo7(ct); break;\r
916 #else\r
917                         case 0:\r
918                         {\r
919                                 /* M1---C1---MEM---M2---C2---OUT */\r
920                                 int m2,c1,c2=0; /* Phase Modulation input for operators 2,3,4 */\r
921                                 m2 = ct->mem;\r
922                                 c1 = ct->op1_out>>16;\r
923                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
924                                         c2  = op_calc(ct->phase3, eg_out,  m2);\r
925                                 }\r
926                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
927                                         ct->mem = op_calc(ct->phase2, eg_out2, c1);\r
928                                 }\r
929                                 else ct->mem = 0;\r
930                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
931                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
932                                 }\r
933                                 break;\r
934                         }\r
935                         case 1:\r
936                         {\r
937                                 /* M1------+-MEM---M2---C2---OUT */\r
938                                 /*      C1-+                     */\r
939                                 int m2,c2=0;\r
940                                 m2 = ct->mem;\r
941                                 ct->mem = ct->op1_out>>16;\r
942                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
943                                         c2  = op_calc(ct->phase3, eg_out,  m2);\r
944                                 }\r
945                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
946                                         ct->mem+= op_calc(ct->phase2, eg_out2, 0);\r
947                                 }\r
948                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
949                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
950                                 }\r
951                                 break;\r
952                         }\r
953                         case 2:\r
954                         {\r
955                                 /* M1-----------------+-C2---OUT */\r
956                                 /*      C1---MEM---M2-+          */\r
957                                 int m2,c2;\r
958                                 m2 = ct->mem;\r
959                                 c2 = ct->op1_out>>16;\r
960                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
961                                         c2 += op_calc(ct->phase3, eg_out,  m2);\r
962                                 }\r
963                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
964                                         ct->mem = op_calc(ct->phase2, eg_out2, 0);\r
965                                 }\r
966                                 else ct->mem = 0;\r
967                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
968                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
969                                 }\r
970                                 break;\r
971                         }\r
972                         case 3:\r
973                         {\r
974                                 /* M1---C1---MEM------+-C2---OUT */\r
975                                 /*                 M2-+          */\r
976                                 int c1,c2;\r
977                                 c2 = ct->mem;\r
978                                 c1 = ct->op1_out>>16;\r
979                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
980                                         c2 += op_calc(ct->phase3, eg_out,  0);\r
981                                 }\r
982                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
983                                         ct->mem = op_calc(ct->phase2, eg_out2, c1);\r
984                                 }\r
985                                 else ct->mem = 0;\r
986                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
987                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
988                                 }\r
989                                 break;\r
990                         }\r
991                         case 4:\r
992                         {\r
993                                 /* M1---C1-+-OUT */\r
994                                 /* M2---C2-+     */\r
995                                 /* MEM: not used */\r
996                                 int c1,c2=0;\r
997                                 c1 = ct->op1_out>>16;\r
998                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
999                                         c2  = op_calc(ct->phase3, eg_out,  0);\r
1000                                 }\r
1001                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1002                                         smp = op_calc(ct->phase2, eg_out2, c1);\r
1003                                 }\r
1004                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1005                                         smp+= op_calc(ct->phase4, eg_out4, c2);\r
1006                                 }\r
1007                                 break;\r
1008                         }\r
1009                         case 5:\r
1010                         {\r
1011                                 /*    +----C1----+     */\r
1012                                 /* M1-+-MEM---M2-+-OUT */\r
1013                                 /*    +----C2----+     */\r
1014                                 int m2,c1,c2;\r
1015                                 m2 = ct->mem;\r
1016                                 ct->mem = c1 = c2 = ct->op1_out>>16;\r
1017                                 if( eg_out < ENV_QUIET ) {              /* SLOT 3 */\r
1018                                         smp = op_calc(ct->phase3, eg_out, m2);\r
1019                                 }\r
1020                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1021                                         smp+= op_calc(ct->phase2, eg_out2, c1);\r
1022                                 }\r
1023                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1024                                         smp+= op_calc(ct->phase4, eg_out4, c2);\r
1025                                 }\r
1026                                 break;\r
1027                         }\r
1028                         case 6:\r
1029                         {\r
1030                                 /* M1---C1-+     */\r
1031                                 /*      M2-+-OUT */\r
1032                                 /*      C2-+     */\r
1033                                 /* MEM: not used */\r
1034                                 int c1;\r
1035                                 c1 = ct->op1_out>>16;\r
1036                                 if( eg_out < ENV_QUIET ) {              /* SLOT 3 */\r
1037                                         smp = op_calc(ct->phase3, eg_out,  0);\r
1038                                 }\r
1039                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1040                                         smp+= op_calc(ct->phase2, eg_out2, c1);\r
1041                                 }\r
1042                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1043                                         smp+= op_calc(ct->phase4, eg_out4, 0);\r
1044                                 }\r
1045                                 break;\r
1046                         }\r
1047                         case 7:\r
1048                         {\r
1049                                 /* M1-+     */\r
1050                                 /* C1-+-OUT */\r
1051                                 /* M2-+     */\r
1052                                 /* C2-+     */\r
1053                                 /* MEM: not used*/\r
1054                                 smp = ct->op1_out>>16;\r
1055                                 if( eg_out < ENV_QUIET ) {              /* SLOT 3 */\r
1056                                         smp += op_calc(ct->phase3, eg_out,  0);\r
1057                                 }\r
1058                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1059                                         smp += op_calc(ct->phase2, eg_out2, 0);\r
1060                                 }\r
1061                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1062                                         smp += op_calc(ct->phase4, eg_out4, 0);\r
1063                                 }\r
1064                                 break;\r
1065                         }\r
1066 #endif\r
1067                 }\r
1068                 /* done calculating channel sample */\r
1069 \r
1070                 /* mix sample to output buffer */\r
1071                 if (smp) {\r
1072                         if (ct->pack & 1) { /* stereo */\r
1073                                 if (ct->pack & 0x20) /* L */ /* TODO: check correctness */\r
1074                                         buffer[scounter*2] += smp;\r
1075                                 if (ct->pack & 0x10) /* R */\r
1076                                         buffer[scounter*2+1] += smp;\r
1077                         } else {\r
1078                                 buffer[scounter] += smp;\r
1079                         }\r
1080                 }\r
1081 \r
1082                 /* update phase counters AFTER output calculations */\r
1083                 ct->phase1 += ct->incr1;\r
1084                 ct->phase2 += ct->incr2;\r
1085                 ct->phase3 += ct->incr3;\r
1086                 ct->phase4 += ct->incr4;\r
1087         }\r
1088 }\r
1089 #else\r
1090 void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);\r
1091 #endif\r
1092 \r
1093 \r
1094 static void chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
1095 {\r
1096         chan_rend_context ct;\r
1097 \r
1098         ct.CH = CH;\r
1099         ct.mem = CH->mem_value;         /* one sample delay memory */\r
1100         ct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
1101         ct.lfo_inc = ym2612.OPN.lfo_inc;\r
1102 \r
1103         flags &= 0x37;\r
1104 \r
1105         if (ct.lfo_inc) {\r
1106                 flags |= 8;\r
1107                 flags |= g_lfo_ampm << 16;\r
1108                 flags |= CH->AMmasks << 8;\r
1109                 if (CH->ams == 8) // no ams\r
1110                          flags &= ~0xf00;\r
1111                 else flags |= (CH->ams&3)<<6;\r
1112         }\r
1113         flags |= (CH->FB&0xf)<<12;                              /* feedback shift */\r
1114         ct.pack = flags;\r
1115 \r
1116         ct.eg_cnt = ym2612.OPN.eg_cnt;                  /* envelope generator counter */\r
1117         ct.eg_timer = ym2612.OPN.eg_timer;\r
1118         ct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
1119 \r
1120         /* precalculate phase modulation incr */\r
1121         ct.phase1 = CH->SLOT[SLOT1].phase;\r
1122         ct.phase2 = CH->SLOT[SLOT2].phase;\r
1123         ct.phase3 = CH->SLOT[SLOT3].phase;\r
1124         ct.phase4 = CH->SLOT[SLOT4].phase;\r
1125 \r
1126         /* current output from EG circuit (without AM from LFO) */\r
1127         ct.vol_out1 = CH->SLOT[SLOT1].tl + ((UINT32)CH->SLOT[SLOT1].volume);\r
1128         ct.vol_out2 = CH->SLOT[SLOT2].tl + ((UINT32)CH->SLOT[SLOT2].volume);\r
1129         ct.vol_out3 = CH->SLOT[SLOT3].tl + ((UINT32)CH->SLOT[SLOT3].volume);\r
1130         ct.vol_out4 = CH->SLOT[SLOT4].tl + ((UINT32)CH->SLOT[SLOT4].volume);\r
1131 \r
1132         ct.op1_out = CH->op1_out;\r
1133         ct.algo = CH->ALGO & 7;\r
1134 \r
1135         if(CH->pms)\r
1136         {\r
1137                 /* add support for 3 slot mode */\r
1138                 UINT32 block_fnum = CH->block_fnum;\r
1139 \r
1140                 UINT32 fnum_lfo   = ((block_fnum & 0x7f0) >> 4) * 32 * 8;\r
1141                 INT32  lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + ((ct.pack>>16)&0xff) ];\r
1142 \r
1143                 if (lfo_fn_table_index_offset)  /* LFO phase modulation active */\r
1144                 {\r
1145                         UINT8  blk;\r
1146                         UINT32 fn;\r
1147                         int kc,fc;\r
1148 \r
1149                         block_fnum = block_fnum*2 + lfo_fn_table_index_offset;\r
1150 \r
1151                         blk = (block_fnum&0x7000) >> 12;\r
1152                         fn  = block_fnum & 0xfff;\r
1153 \r
1154                         /* keyscale code */\r
1155                         kc = (blk<<2) | opn_fktable[fn >> 8];\r
1156                         /* phase increment counter */\r
1157                         fc = fn_table[fn]>>(7-blk);\r
1158 \r
1159                         ct.incr1 = ((fc+CH->SLOT[SLOT1].DT[kc])*CH->SLOT[SLOT1].mul) >> 1;\r
1160                         ct.incr2 = ((fc+CH->SLOT[SLOT2].DT[kc])*CH->SLOT[SLOT2].mul) >> 1;\r
1161                         ct.incr3 = ((fc+CH->SLOT[SLOT3].DT[kc])*CH->SLOT[SLOT3].mul) >> 1;\r
1162                         ct.incr4 = ((fc+CH->SLOT[SLOT4].DT[kc])*CH->SLOT[SLOT4].mul) >> 1;\r
1163                 }\r
1164                 else    /* LFO phase modulation  = zero */\r
1165                 {\r
1166                         ct.incr1 = CH->SLOT[SLOT1].Incr;\r
1167                         ct.incr2 = CH->SLOT[SLOT2].Incr;\r
1168                         ct.incr3 = CH->SLOT[SLOT3].Incr;\r
1169                         ct.incr4 = CH->SLOT[SLOT4].Incr;\r
1170                 }\r
1171         }\r
1172         else    /* no LFO phase modulation */\r
1173         {\r
1174                 ct.incr1 = CH->SLOT[SLOT1].Incr;\r
1175                 ct.incr2 = CH->SLOT[SLOT2].Incr;\r
1176                 ct.incr3 = CH->SLOT[SLOT3].Incr;\r
1177                 ct.incr4 = CH->SLOT[SLOT4].Incr;\r
1178         }\r
1179 \r
1180         chan_render_loop(&ct, buffer, length);\r
1181 \r
1182         // write back persistent stuff:\r
1183         if (flags & 2) { /* last channel */\r
1184                 ym2612.OPN.eg_cnt = ct.eg_cnt;\r
1185                 ym2612.OPN.eg_timer = ct.eg_timer;\r
1186                 g_lfo_ampm = ct.pack >> 16;\r
1187                 ym2612.OPN.lfo_cnt = ct.lfo_cnt;\r
1188         }\r
1189 \r
1190         CH->op1_out = ct.op1_out;\r
1191         CH->SLOT[SLOT1].phase = ct.phase1;\r
1192         CH->SLOT[SLOT2].phase = ct.phase2;\r
1193         CH->SLOT[SLOT3].phase = ct.phase3;\r
1194         CH->SLOT[SLOT4].phase = ct.phase4;\r
1195         CH->mem_value = ct.mem;\r
1196 }\r
1197 \r
1198 /* update phase increment and envelope generator */\r
1199 INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT, int fc, int kc)\r
1200 {\r
1201         int ksr;\r
1202 \r
1203         /* (frequency) phase increment counter */\r
1204         SLOT->Incr = ((fc+SLOT->DT[kc])*SLOT->mul) >> 1;\r
1205 \r
1206         ksr = kc >> SLOT->KSR;\r
1207         if( SLOT->ksr != ksr )\r
1208         {\r
1209                 int eg_sh, eg_sel;\r
1210                 SLOT->ksr = ksr;\r
1211 \r
1212                 /* calculate envelope generator rates */\r
1213                 if ((SLOT->ar + SLOT->ksr) < 32+62)\r
1214                 {\r
1215                         eg_sh  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];\r
1216                         eg_sel = eg_rate_select[SLOT->ar  + SLOT->ksr ];\r
1217                 }\r
1218                 else\r
1219                 {\r
1220                         eg_sh  = 0;\r
1221                         eg_sel = 17;\r
1222                 }\r
1223 \r
1224                 SLOT->eg_pack_ar = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1225 \r
1226                 eg_sh  = eg_rate_shift [SLOT->d1r + SLOT->ksr];\r
1227                 eg_sel = eg_rate_select[SLOT->d1r + SLOT->ksr];\r
1228 \r
1229                 SLOT->eg_pack_d1r = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1230 \r
1231                 eg_sh  = eg_rate_shift [SLOT->d2r + SLOT->ksr];\r
1232                 eg_sel = eg_rate_select[SLOT->d2r + SLOT->ksr];\r
1233 \r
1234                 SLOT->eg_pack_d2r = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1235 \r
1236                 eg_sh  = eg_rate_shift [SLOT->rr  + SLOT->ksr];\r
1237                 eg_sel = eg_rate_select[SLOT->rr  + SLOT->ksr];\r
1238 \r
1239                 SLOT->eg_pack_rr = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1240         }\r
1241 }\r
1242 \r
1243 /* update phase increment counters */\r
1244 INLINE void refresh_fc_eg_chan(FM_CH *CH)\r
1245 {\r
1246         if( CH->SLOT[SLOT1].Incr==-1){\r
1247                 int fc = CH->fc;\r
1248                 int kc = CH->kcode;\r
1249                 refresh_fc_eg_slot(&CH->SLOT[SLOT1] , fc , kc );\r
1250                 refresh_fc_eg_slot(&CH->SLOT[SLOT2] , fc , kc );\r
1251                 refresh_fc_eg_slot(&CH->SLOT[SLOT3] , fc , kc );\r
1252                 refresh_fc_eg_slot(&CH->SLOT[SLOT4] , fc , kc );\r
1253         }\r
1254 }\r
1255 \r
1256 /* initialize time tables */\r
1257 static void init_timetables(const UINT8 *dttable)\r
1258 {\r
1259         int i,d;\r
1260         double rate;\r
1261 \r
1262         /* DeTune table */\r
1263         for (d = 0;d <= 3;d++){\r
1264                 for (i = 0;i <= 31;i++){\r
1265                         rate = ((double)dttable[d*32 + i]) * SIN_LEN  * ym2612.OPN.ST.freqbase  * (1<<FREQ_SH) / ((double)(1<<20));\r
1266                         ym2612.OPN.ST.dt_tab[d][i]   = (INT32) rate;\r
1267                         ym2612.OPN.ST.dt_tab[d+4][i] = -ym2612.OPN.ST.dt_tab[d][i];\r
1268                 }\r
1269         }\r
1270 }\r
1271 \r
1272 \r
1273 static void reset_channels(FM_CH *CH, int num)\r
1274 {\r
1275         int c,s;\r
1276 \r
1277         ym2612.OPN.ST.mode   = 0;       /* normal mode */\r
1278         ym2612.OPN.ST.TA     = 0;\r
1279         ym2612.OPN.ST.TAC    = 0;\r
1280         ym2612.OPN.ST.TB     = 0;\r
1281         ym2612.OPN.ST.TBC    = 0;\r
1282 \r
1283         for( c = 0 ; c < num ; c++ )\r
1284         {\r
1285                 CH[c].fc = 0;\r
1286                 for(s = 0 ; s < 4 ; s++ )\r
1287                 {\r
1288                         CH[c].SLOT[s].state= EG_OFF;\r
1289                         CH[c].SLOT[s].volume = MAX_ATT_INDEX;\r
1290                 }\r
1291         }\r
1292 }\r
1293 \r
1294 /* initialize generic tables */\r
1295 static void init_tables(void)\r
1296 {\r
1297         signed int i,x,y,p;\r
1298         signed int n;\r
1299         double o,m;\r
1300 \r
1301         for (i=0; i < 256; i++)\r
1302         {\r
1303                 /* non-standard sinus */\r
1304                 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */\r
1305 \r
1306                 /* we never reach zero here due to ((i*2)+1) */\r
1307 \r
1308                 if (m>0.0)\r
1309                         o = 8*log(1.0/m)/log(2);        /* convert to 'decibels' */\r
1310                 else\r
1311                         o = 8*log(-1.0/m)/log(2);       /* convert to 'decibels' */\r
1312 \r
1313                 o = o / (ENV_STEP/4);\r
1314 \r
1315                 n = (int)(2.0*o);\r
1316                 if (n&1)                                                /* round to nearest */\r
1317                         n = (n>>1)+1;\r
1318                 else\r
1319                         n = n>>1;\r
1320 \r
1321                 ym_sin_tab[ i ] = n;\r
1322                 //dprintf("FM.C: sin [%4i]= %4i", i, ym_sin_tab[i]);\r
1323         }\r
1324 \r
1325         //dprintf("FM.C: ENV_QUIET= %08x", ENV_QUIET );\r
1326 \r
1327 \r
1328         for (x=0; x < TL_RES_LEN; x++)\r
1329         {\r
1330                 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);\r
1331                 m = floor(m);\r
1332 \r
1333                 /* we never reach (1<<16) here due to the (x+1) */\r
1334                 /* result fits within 16 bits at maximum */\r
1335 \r
1336                 n = (int)m;             /* 16 bits here */\r
1337                 n >>= 4;                /* 12 bits here */\r
1338                 if (n&1)                /* round to nearest */\r
1339                         n = (n>>1)+1;\r
1340                 else\r
1341                         n = n>>1;\r
1342                                                 /* 11 bits here (rounded) */\r
1343                 n <<= 2;                /* 13 bits here (as in real chip) */\r
1344                 ym_tl_tab2[ x ] = n;\r
1345 \r
1346                 for (i=1; i < 13; i++)\r
1347                 {\r
1348                         ym_tl_tab2[ x + i*TL_RES_LEN ] = n >> i;\r
1349                 }\r
1350         }\r
1351 \r
1352         for (x=0; x < 256; x++)\r
1353         {\r
1354                 int sin = ym_sin_tab[ x ];\r
1355 \r
1356                 for (y=0; y < 2*13*TL_RES_LEN/8; y+=2)\r
1357                 {\r
1358                         p = (y<<2) + sin;\r
1359                         if (p >= 13*TL_RES_LEN)\r
1360                                  ym_tl_tab[(y<<7) | x] = 0;\r
1361                         else ym_tl_tab[(y<<7) | x] = ym_tl_tab2[p];\r
1362                 }\r
1363         }\r
1364 \r
1365 \r
1366         /* build LFO PM modulation table */\r
1367         for(i = 0; i < 8; i++) /* 8 PM depths */\r
1368         {\r
1369                 UINT8 fnum;\r
1370                 for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */\r
1371                 {\r
1372                         UINT8 value;\r
1373                         UINT8 step;\r
1374                         UINT32 offset_depth = i;\r
1375                         UINT32 offset_fnum_bit;\r
1376                         UINT32 bit_tmp;\r
1377 \r
1378                         for (step=0; step<8; step++)\r
1379                         {\r
1380                                 value = 0;\r
1381                                 for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */\r
1382                                 {\r
1383                                         if (fnum & (1<<bit_tmp)) /* only if bit "bit_tmp" is set */\r
1384                                         {\r
1385                                                 offset_fnum_bit = bit_tmp * 8;\r
1386                                                 value += lfo_pm_output[offset_fnum_bit + offset_depth][step];\r
1387                                         }\r
1388                                 }\r
1389                                 lfo_pm_table[(fnum*32*8) + (i*32) + step   + 0] = value;\r
1390                                 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+ 8] = value;\r
1391                                 lfo_pm_table[(fnum*32*8) + (i*32) + step   +16] = -value;\r
1392                                 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+24] = -value;\r
1393                         }\r
1394                 }\r
1395         }\r
1396 }\r
1397 \r
1398 \r
1399 /* CSM Key Controll */\r
1400 INLINE void CSMKeyControll(FM_CH *CH)\r
1401 {\r
1402         /* this is wrong, atm */\r
1403 \r
1404         /* all key on */\r
1405         FM_KEYON(CH,SLOT1);\r
1406         FM_KEYON(CH,SLOT2);\r
1407         FM_KEYON(CH,SLOT3);\r
1408         FM_KEYON(CH,SLOT4);\r
1409 }\r
1410 \r
1411 \r
1412 /* prescaler set (and make time tables) */\r
1413 static void OPNSetPres(int pres)\r
1414 {\r
1415         int i;\r
1416 \r
1417         /* frequency base */\r
1418         ym2612.OPN.ST.freqbase = (ym2612.OPN.ST.rate) ? ((double)ym2612.OPN.ST.clock / ym2612.OPN.ST.rate) / pres : 0;\r
1419 \r
1420         ym2612.OPN.eg_timer_add  = (1<<EG_SH) * ym2612.OPN.ST.freqbase;\r
1421 \r
1422 \r
1423         /* make time tables */\r
1424         init_timetables( dt_tab );\r
1425 \r
1426         /* there are 2048 FNUMs that can be generated using FNUM/BLK registers\r
1427         but LFO works with one more bit of a precision so we really need 4096 elements */\r
1428         /* calculate fnumber -> increment counter table */\r
1429         for(i = 0; i < 4096; i++)\r
1430         {\r
1431                 /* freq table for octave 7 */\r
1432                 /* OPN phase increment counter = 20bit */\r
1433                 fn_table[i] = (UINT32)( (double)i * 32 * ym2612.OPN.ST.freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */\r
1434         }\r
1435 \r
1436         /* LFO freq. table */\r
1437         for(i = 0; i < 8; i++)\r
1438         {\r
1439                 /* Amplitude modulation: 64 output levels (triangle waveform); 1 level lasts for one of "lfo_samples_per_step" samples */\r
1440                 /* Phase modulation: one entry from lfo_pm_output lasts for one of 4 * "lfo_samples_per_step" samples  */\r
1441                 ym2612.OPN.lfo_freq[i] = (1.0 / lfo_samples_per_step[i]) * (1<<LFO_SH) * ym2612.OPN.ST.freqbase;\r
1442         }\r
1443 }\r
1444 \r
1445 \r
1446 /* write a OPN register (0x30-0xff) */\r
1447 static int OPNWriteReg(int r, int v)\r
1448 {\r
1449         int ret = 1;\r
1450         FM_CH *CH;\r
1451         FM_SLOT *SLOT;\r
1452 \r
1453         UINT8 c = OPN_CHAN(r);\r
1454 \r
1455         if (c == 3) return 0; /* 0xX3,0xX7,0xXB,0xXF */\r
1456 \r
1457         if (r >= 0x100) c+=3;\r
1458 \r
1459         CH = &ym2612.CH[c];\r
1460 \r
1461         SLOT = &(CH->SLOT[OPN_SLOT(r)]);\r
1462 \r
1463         switch( r & 0xf0 ) {\r
1464         case 0x30:      /* DET , MUL */\r
1465                 set_det_mul(CH,SLOT,v);\r
1466                 break;\r
1467 \r
1468         case 0x40:      /* TL */\r
1469                 set_tl(SLOT,v);\r
1470                 break;\r
1471 \r
1472         case 0x50:      /* KS, AR */\r
1473                 set_ar_ksr(CH,SLOT,v);\r
1474                 break;\r
1475 \r
1476         case 0x60:      /* bit7 = AM ENABLE, DR */\r
1477                 set_dr(SLOT,v);\r
1478                 if(v&0x80) CH->AMmasks |=   1<<OPN_SLOT(r);\r
1479                 else       CH->AMmasks &= ~(1<<OPN_SLOT(r));\r
1480                 break;\r
1481 \r
1482         case 0x70:      /*     SR */\r
1483                 set_sr(SLOT,v);\r
1484                 break;\r
1485 \r
1486         case 0x80:      /* SL, RR */\r
1487                 set_sl_rr(SLOT,v);\r
1488                 break;\r
1489 \r
1490         case 0x90:      /* SSG-EG */\r
1491                 // removed.\r
1492                 ret = 0;\r
1493                 break;\r
1494 \r
1495         case 0xa0:\r
1496                 switch( OPN_SLOT(r) ){\r
1497                 case 0:         /* 0xa0-0xa2 : FNUM1 */\r
1498                         {\r
1499                                 UINT32 fn = (((UINT32)( (ym2612.OPN.ST.fn_h)&7))<<8) + v;\r
1500                                 UINT8 blk = ym2612.OPN.ST.fn_h>>3;\r
1501                                 /* keyscale code */\r
1502                                 CH->kcode = (blk<<2) | opn_fktable[fn >> 7];\r
1503                                 /* phase increment counter */\r
1504                                 CH->fc = fn_table[fn*2]>>(7-blk);\r
1505 \r
1506                                 /* store fnum in clear form for LFO PM calculations */\r
1507                                 CH->block_fnum = (blk<<11) | fn;\r
1508 \r
1509                                 CH->SLOT[SLOT1].Incr=-1;\r
1510                         }\r
1511                         break;\r
1512                 case 1:         /* 0xa4-0xa6 : FNUM2,BLK */\r
1513                         ym2612.OPN.ST.fn_h = v&0x3f;\r
1514                         ret = 0;\r
1515                         break;\r
1516                 case 2:         /* 0xa8-0xaa : 3CH FNUM1 */\r
1517                         if(r < 0x100)\r
1518                         {\r
1519                                 UINT32 fn = (((UINT32)(ym2612.OPN.SL3.fn_h&7))<<8) + v;\r
1520                                 UINT8 blk = ym2612.OPN.SL3.fn_h>>3;\r
1521                                 /* keyscale code */\r
1522                                 ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];\r
1523                                 /* phase increment counter */\r
1524                                 ym2612.OPN.SL3.fc[c] = fn_table[fn*2]>>(7-blk);\r
1525                                 ym2612.OPN.SL3.block_fnum[c] = fn;\r
1526                                 ym2612.CH[2].SLOT[SLOT1].Incr=-1;\r
1527                         }\r
1528                         break;\r
1529                 case 3:         /* 0xac-0xae : 3CH FNUM2,BLK */\r
1530                         if(r < 0x100)\r
1531                                 ym2612.OPN.SL3.fn_h = v&0x3f;\r
1532                         ret = 0;\r
1533                         break;\r
1534                 default:\r
1535                         ret = 0;\r
1536                         break;\r
1537                 }\r
1538                 break;\r
1539 \r
1540         case 0xb0:\r
1541                 switch( OPN_SLOT(r) ){\r
1542                 case 0:         /* 0xb0-0xb2 : FB,ALGO */\r
1543                         {\r
1544                                 int feedback = (v>>3)&7;\r
1545                                 CH->ALGO = v&7;\r
1546                                 CH->FB   = feedback ? feedback+6 : 0;\r
1547                         }\r
1548                         break;\r
1549                 case 1:         /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */\r
1550                         {\r
1551                                 int panshift = c<<1;\r
1552 \r
1553                                 /* b0-2 PMS */\r
1554                                 CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */\r
1555 \r
1556                                 /* b4-5 AMS */\r
1557                                 CH->ams = lfo_ams_depth_shift[(v>>4) & 3];\r
1558 \r
1559                                 /* PAN :  b7 = L, b6 = R */\r
1560                                 ym2612.OPN.pan &= ~(3<<panshift);\r
1561                                 ym2612.OPN.pan |= ((v & 0xc0) >> 6) << panshift; // ..LRLR\r
1562                         }\r
1563                         break;\r
1564                 default:\r
1565                         ret = 0;\r
1566                         break;\r
1567                 }\r
1568                 break;\r
1569         default:\r
1570                 ret = 0;\r
1571                 break;\r
1572         }\r
1573 \r
1574         return ret;\r
1575 }\r
1576 \r
1577 \r
1578 /*******************************************************************************/\r
1579 /*      YM2612 local section                                                   */\r
1580 /*******************************************************************************/\r
1581 \r
1582 int   *ym2612_dacen;\r
1583 INT32 *ym2612_dacout;\r
1584 \r
1585 \r
1586 /* Generate samples for YM2612 */\r
1587 void YM2612UpdateOne_(short *buffer, int length, int stereo)\r
1588 {\r
1589         int pan;\r
1590 #ifndef EXTERNAL_YM2612\r
1591         int i;\r
1592         static int *mix_buffer = 0, mix_buffer_length = 0;\r
1593 #endif\r
1594 \r
1595         /* refresh PG and EG */\r
1596         refresh_fc_eg_chan( &ym2612.CH[0] );\r
1597         refresh_fc_eg_chan( &ym2612.CH[1] );\r
1598         if( (ym2612.OPN.ST.mode & 0xc0) )\r
1599         {\r
1600                 /* 3SLOT MODE */\r
1601                 if( ym2612.CH[2].SLOT[SLOT1].Incr==-1)\r
1602                 {\r
1603                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT1], ym2612.OPN.SL3.fc[1], ym2612.OPN.SL3.kcode[1] );\r
1604                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT2], ym2612.OPN.SL3.fc[2], ym2612.OPN.SL3.kcode[2] );\r
1605                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT3], ym2612.OPN.SL3.fc[0], ym2612.OPN.SL3.kcode[0] );\r
1606                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT4], ym2612.CH[2].fc , ym2612.CH[2].kcode );\r
1607                 }\r
1608         } else refresh_fc_eg_chan( &ym2612.CH[2] );\r
1609         refresh_fc_eg_chan( &ym2612.CH[3] );\r
1610         refresh_fc_eg_chan( &ym2612.CH[4] );\r
1611         refresh_fc_eg_chan( &ym2612.CH[5] );\r
1612 \r
1613         pan = ym2612.OPN.pan;\r
1614         if (stereo) stereo = 1;\r
1615 \r
1616 #ifndef EXTERNAL_YM2612\r
1617         if (mix_buffer_length < length) {\r
1618                 mix_buffer = realloc(mix_buffer, length*4<<stereo); // FIXME: need to free this at some point\r
1619                 if (!mix_buffer) return;\r
1620                 mix_buffer_length = length;\r
1621         }\r
1622 #endif\r
1623         memset(mix_buffer, 0, length*4<<stereo);\r
1624 \r
1625         /* mix to 32bit temporary buffer */\r
1626         chan_render(mix_buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)); // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
1627         chan_render(mix_buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2));\r
1628         chan_render(mix_buffer, length, &ym2612.CH[2], stereo|((pan&0x030)   ));\r
1629         chan_render(mix_buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2));\r
1630         chan_render(mix_buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4));\r
1631         chan_render(mix_buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2);\r
1632 \r
1633 #ifndef EXTERNAL_YM2612\r
1634         /* limit and mix to output buffer */\r
1635         if (stereo) {\r
1636                 int *mb = mix_buffer;\r
1637                 for (i = length; i > 0; i--) {\r
1638                         int l, r;\r
1639                         l = r = *buffer;\r
1640                         l += *mb++, r += *mb++;\r
1641                         Limit( l, MAXOUT, MINOUT );\r
1642                         Limit( r, MAXOUT, MINOUT );\r
1643                         *buffer++ = l; *buffer++ = r;\r
1644                 }\r
1645         } else {\r
1646                 for (i = 0; i < length; i++) {\r
1647                         int l = mix_buffer[i];\r
1648                         l += buffer[i];\r
1649                         Limit( l, MAXOUT, MINOUT );\r
1650                         buffer[i] = l;\r
1651                 }\r
1652         }\r
1653 #endif\r
1654 }\r
1655 \r
1656 \r
1657 /* initialize YM2612 emulator */\r
1658 void YM2612Init_(int clock, int rate)\r
1659 {\r
1660         // notaz\r
1661         ym2612_dacen = &ym2612.dacen;\r
1662         ym2612_dacout = &ym2612.dacout;\r
1663 \r
1664         /* clear everything but the regs */\r
1665         memset(ym2612.CH, 0, sizeof(ym2612)-sizeof(ym2612.REGS)-4);\r
1666         init_tables();\r
1667 \r
1668         ym2612.OPN.ST.clock = clock;\r
1669         ym2612.OPN.ST.rate = rate;\r
1670 \r
1671         /* Extend handler */\r
1672         YM2612ResetChip_();\r
1673 }\r
1674 \r
1675 \r
1676 /* reset */\r
1677 void YM2612ResetChip_(void)\r
1678 {\r
1679         int i;\r
1680 \r
1681         OPNSetPres( 6*24 );\r
1682         set_timers( 0x30 ); /* mode 0 , timer reset */\r
1683 \r
1684         ym2612.OPN.eg_timer = 0;\r
1685         ym2612.OPN.eg_cnt   = 0;\r
1686         ym2612.OPN.ST.status = 0;\r
1687 \r
1688         reset_channels( &ym2612.CH[0] , 6 );\r
1689         for(i = 0xb6 ; i >= 0xb4 ; i-- )\r
1690         {\r
1691                 OPNWriteReg(i      ,0xc0);\r
1692                 OPNWriteReg(i|0x100,0xc0);\r
1693         }\r
1694         for(i = 0xb2 ; i >= 0x30 ; i-- )\r
1695         {\r
1696                 OPNWriteReg(i      ,0);\r
1697                 OPNWriteReg(i|0x100,0);\r
1698         }\r
1699         for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0);\r
1700         /* DAC mode clear */\r
1701         ym2612.dacen = 0;\r
1702 }\r
1703 \r
1704 \r
1705 /* YM2612 write */\r
1706 /* a = address */\r
1707 /* v = value   */\r
1708 /* returns 1 if sample affecting state changed */\r
1709 int YM2612Write_(unsigned int a, unsigned int v)\r
1710 {\r
1711         int addr, ret=1;\r
1712 \r
1713         v &= 0xff;      /* adjust to 8 bit bus */\r
1714 \r
1715         switch( a&3){\r
1716         case 0: /* address port 0 */\r
1717                 ym2612.OPN.ST.address = v;\r
1718                 ym2612.addr_A1 = 0;\r
1719                 ret=0;\r
1720                 break;\r
1721 \r
1722         case 1: /* data port 0    */\r
1723                 if (ym2612.addr_A1 != 0) {\r
1724                         ret=0;\r
1725                         break;  /* verified on real YM2608 */\r
1726                 }\r
1727 \r
1728                 addr = ym2612.OPN.ST.address;\r
1729                 ym2612.REGS[addr] = v;\r
1730 \r
1731                 switch( addr & 0xf0 )\r
1732                 {\r
1733                 case 0x20:      /* 0x20-0x2f Mode */\r
1734                         switch( addr )\r
1735                         {\r
1736                         case 0x22:      /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */\r
1737                                 if (v&0x08) /* LFO enabled ? */\r
1738                                 {\r
1739                                         ym2612.OPN.lfo_inc = ym2612.OPN.lfo_freq[v&7];\r
1740                                 }\r
1741                                 else\r
1742                                 {\r
1743                                         ym2612.OPN.lfo_inc = 0;\r
1744                                 }\r
1745                                 break;\r
1746                         case 0x24: { // timer A High 8\r
1747                                         int TAnew = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2);\r
1748                                         if(ym2612.OPN.ST.TA != TAnew) {\r
1749                                                 // we should reset ticker only if new value is written. Outrun requires this.\r
1750                                                 ym2612.OPN.ST.TA = TAnew;\r
1751                                                 ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
1752                                                 ym2612.OPN.ST.TAT = 0;\r
1753                                         }\r
1754                                 }\r
1755                                 ret=0;\r
1756                                 break;\r
1757                         case 0x25: { // timer A Low 2\r
1758                                         int TAnew = (ym2612.OPN.ST.TA & 0x3fc)|(v&3);\r
1759                                         if(ym2612.OPN.ST.TA != TAnew) {\r
1760                                                 ym2612.OPN.ST.TA = TAnew;\r
1761                                                 ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
1762                                                 ym2612.OPN.ST.TAT = 0;\r
1763                                         }\r
1764                                 }\r
1765                                 ret=0;\r
1766                                 break;\r
1767                         case 0x26: // timer B\r
1768                                 if(ym2612.OPN.ST.TB != v) {\r
1769                                         ym2612.OPN.ST.TB = v;\r
1770                                         ym2612.OPN.ST.TBC  = (256-v)<<4;\r
1771                                         ym2612.OPN.ST.TBC *= 18;\r
1772                                         ym2612.OPN.ST.TBT  = 0;\r
1773                                 }\r
1774                                 ret=0;\r
1775                                 break;\r
1776                         case 0x27:      /* mode, timer control */\r
1777                                 set_timers( v );\r
1778                                 ret=0;\r
1779                                 break;\r
1780                         case 0x28:      /* key on / off */\r
1781                                 {\r
1782                                         UINT8 c;\r
1783                                         FM_CH *CH;\r
1784 \r
1785                                         c = v & 0x03;\r
1786                                         if( c == 3 ) { ret=0; break; }\r
1787                                         if( v&0x04 ) c+=3;\r
1788                                         CH = &ym2612.CH[c];\r
1789                                         if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);\r
1790                                         if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);\r
1791                                         if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);\r
1792                                         if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);\r
1793                                         break;\r
1794                                 }\r
1795                         case 0x2a:      /* DAC data (YM2612) */\r
1796                                 ym2612.dacout = ((int)v - 0x80) << 6;   /* level unknown (notaz: 8 seems to be too much) */\r
1797                                 ret=0;\r
1798                                 break;\r
1799                         case 0x2b:      /* DAC Sel  (YM2612) */\r
1800                                 /* b7 = dac enable */\r
1801                                 ym2612.dacen = v & 0x80;\r
1802                                 ret=0;\r
1803                                 break;\r
1804                         default:\r
1805                                 break;\r
1806                         }\r
1807                         break;\r
1808                 default:        /* 0x30-0xff OPN section */\r
1809                         /* write register */\r
1810                         ret = OPNWriteReg(addr,v);\r
1811                 }\r
1812                 break;\r
1813 \r
1814         case 2: /* address port 1 */\r
1815                 ym2612.OPN.ST.address = v;\r
1816                 ym2612.addr_A1 = 1;\r
1817                 ret=0;\r
1818                 break;\r
1819 \r
1820         case 3: /* data port 1    */\r
1821                 if (ym2612.addr_A1 != 1) {\r
1822                         ret=0;\r
1823                         break;  /* verified on real YM2608 */\r
1824                 }\r
1825 \r
1826                 addr = ym2612.OPN.ST.address | 0x100;\r
1827                 ym2612.REGS[addr] = v;\r
1828 \r
1829                 ret = OPNWriteReg(addr, v);\r
1830                 break;\r
1831         }\r
1832 /*\r
1833         if(ret) {\r
1834                 extern int Scanline;\r
1835                 dprintf("ymw [%i]", Scanline);\r
1836         }\r
1837 */\r
1838         return ret;\r
1839 }\r
1840 \r
1841 UINT8 YM2612Read_(void)\r
1842 {\r
1843         return ym2612.OPN.ST.status;\r
1844 }\r
1845 \r
1846 \r
1847 int YM2612PicoTick_(int n)\r
1848 {\r
1849         int ret = 0;\r
1850 \r
1851         // timer A\r
1852         if(ym2612.OPN.ST.mode & 0x01 && (ym2612.OPN.ST.TAT+=64*n) >= ym2612.OPN.ST.TAC) {\r
1853                 ym2612.OPN.ST.TAT -= ym2612.OPN.ST.TAC;\r
1854                 if(ym2612.OPN.ST.mode & 0x04) ym2612.OPN.ST.status |= 1;\r
1855                 // CSM mode total level latch and auto key on\r
1856                 if(ym2612.OPN.ST.mode & 0x80) {\r
1857                         CSMKeyControll( &(ym2612.CH[2]) ); // Vectorman2, etc.\r
1858                         ret = 1;\r
1859                 }\r
1860         }\r
1861 \r
1862         // timer B\r
1863         if(ym2612.OPN.ST.mode & 0x02 && (ym2612.OPN.ST.TBT+=64*n) >= ym2612.OPN.ST.TBC) {\r
1864                 ym2612.OPN.ST.TBT -= ym2612.OPN.ST.TBC;\r
1865                 if(ym2612.OPN.ST.mode & 0x08) ym2612.OPN.ST.status |= 2;\r
1866         }\r
1867 \r
1868         return ret;\r
1869 }\r
1870 \r
1871 \r
1872 void YM2612PicoStateLoad_(void)\r
1873 {\r
1874 #ifndef EXTERNAL_YM2612\r
1875         int i, old_A1 = ym2612.addr_A1;\r
1876 \r
1877         reset_channels( &ym2612.CH[0], 6 );\r
1878 \r
1879         // feed all the registers and update internal state\r
1880         for(i = 0; i < 0x100; i++) {\r
1881                 YM2612Write_(0, i);\r
1882                 YM2612Write_(1, ym2612.REGS[i]);\r
1883         }\r
1884         for(i = 0; i < 0x100; i++) {\r
1885                 YM2612Write_(2, i);\r
1886                 YM2612Write_(3, ym2612.REGS[i|0x100]);\r
1887         }\r
1888 \r
1889         ym2612.addr_A1 = old_A1;\r
1890 #else\r
1891         reset_channels( &ym2612.CH[0], 6 );\r
1892 #endif\r
1893 }\r
1894 \r
1895 \r
1896 void *YM2612GetRegs(void)\r
1897 {\r
1898         return ym2612.REGS;\r
1899 }\r