audio improvement wip
[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 #include "mix.h"\r
116 \r
117 #ifndef EXTERNAL_YM2612\r
118 #include <stdlib.h>\r
119 // let it be 1 global to simplify things\r
120 static YM2612 ym2612;\r
121 \r
122 #else\r
123 extern YM2612 *ym2612_940;\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: algo[3], was_update */\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                         ct->algo = 8; // algo is only used in asm, here only bit3 is used\r
1081                 }\r
1082 \r
1083                 /* update phase counters AFTER output calculations */\r
1084                 ct->phase1 += ct->incr1;\r
1085                 ct->phase2 += ct->incr2;\r
1086                 ct->phase3 += ct->incr3;\r
1087                 ct->phase4 += ct->incr4;\r
1088         }\r
1089 }\r
1090 #else\r
1091 void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);\r
1092 #endif\r
1093 \r
1094 \r
1095 static int chan_render(int *buffer, int length, FM_CH *CH, UINT32 flags) // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
1096 {\r
1097         chan_rend_context ct;\r
1098 \r
1099         ct.CH = CH;\r
1100         ct.mem = CH->mem_value;         /* one sample delay memory */\r
1101         ct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
1102         ct.lfo_inc = ym2612.OPN.lfo_inc;\r
1103 \r
1104         flags &= 0x37;\r
1105 \r
1106         if (ct.lfo_inc) {\r
1107                 flags |= 8;\r
1108                 flags |= g_lfo_ampm << 16;\r
1109                 flags |= CH->AMmasks << 8;\r
1110                 if (CH->ams == 8) // no ams\r
1111                          flags &= ~0xf00;\r
1112                 else flags |= (CH->ams&3)<<6;\r
1113         }\r
1114         flags |= (CH->FB&0xf)<<12;                              /* feedback shift */\r
1115         ct.pack = flags;\r
1116 \r
1117         ct.eg_cnt = ym2612.OPN.eg_cnt;                  /* envelope generator counter */\r
1118         ct.eg_timer = ym2612.OPN.eg_timer;\r
1119         ct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
1120 \r
1121         /* precalculate phase modulation incr */\r
1122         ct.phase1 = CH->SLOT[SLOT1].phase;\r
1123         ct.phase2 = CH->SLOT[SLOT2].phase;\r
1124         ct.phase3 = CH->SLOT[SLOT3].phase;\r
1125         ct.phase4 = CH->SLOT[SLOT4].phase;\r
1126 \r
1127         /* current output from EG circuit (without AM from LFO) */\r
1128         ct.vol_out1 = CH->SLOT[SLOT1].tl + ((UINT32)CH->SLOT[SLOT1].volume);\r
1129         ct.vol_out2 = CH->SLOT[SLOT2].tl + ((UINT32)CH->SLOT[SLOT2].volume);\r
1130         ct.vol_out3 = CH->SLOT[SLOT3].tl + ((UINT32)CH->SLOT[SLOT3].volume);\r
1131         ct.vol_out4 = CH->SLOT[SLOT4].tl + ((UINT32)CH->SLOT[SLOT4].volume);\r
1132 \r
1133         ct.op1_out = CH->op1_out;\r
1134         ct.algo = CH->ALGO & 7;\r
1135 \r
1136         if(CH->pms)\r
1137         {\r
1138                 /* add support for 3 slot mode */\r
1139                 UINT32 block_fnum = CH->block_fnum;\r
1140 \r
1141                 UINT32 fnum_lfo   = ((block_fnum & 0x7f0) >> 4) * 32 * 8;\r
1142                 INT32  lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + ((ct.pack>>16)&0xff) ];\r
1143 \r
1144                 if (lfo_fn_table_index_offset)  /* LFO phase modulation active */\r
1145                 {\r
1146                         UINT8  blk;\r
1147                         UINT32 fn;\r
1148                         int kc,fc;\r
1149 \r
1150                         block_fnum = block_fnum*2 + lfo_fn_table_index_offset;\r
1151 \r
1152                         blk = (block_fnum&0x7000) >> 12;\r
1153                         fn  = block_fnum & 0xfff;\r
1154 \r
1155                         /* keyscale code */\r
1156                         kc = (blk<<2) | opn_fktable[fn >> 8];\r
1157                         /* phase increment counter */\r
1158                         fc = fn_table[fn]>>(7-blk);\r
1159 \r
1160                         ct.incr1 = ((fc+CH->SLOT[SLOT1].DT[kc])*CH->SLOT[SLOT1].mul) >> 1;\r
1161                         ct.incr2 = ((fc+CH->SLOT[SLOT2].DT[kc])*CH->SLOT[SLOT2].mul) >> 1;\r
1162                         ct.incr3 = ((fc+CH->SLOT[SLOT3].DT[kc])*CH->SLOT[SLOT3].mul) >> 1;\r
1163                         ct.incr4 = ((fc+CH->SLOT[SLOT4].DT[kc])*CH->SLOT[SLOT4].mul) >> 1;\r
1164                 }\r
1165                 else    /* LFO phase modulation  = zero */\r
1166                 {\r
1167                         ct.incr1 = CH->SLOT[SLOT1].Incr;\r
1168                         ct.incr2 = CH->SLOT[SLOT2].Incr;\r
1169                         ct.incr3 = CH->SLOT[SLOT3].Incr;\r
1170                         ct.incr4 = CH->SLOT[SLOT4].Incr;\r
1171                 }\r
1172         }\r
1173         else    /* no LFO phase modulation */\r
1174         {\r
1175                 ct.incr1 = CH->SLOT[SLOT1].Incr;\r
1176                 ct.incr2 = CH->SLOT[SLOT2].Incr;\r
1177                 ct.incr3 = CH->SLOT[SLOT3].Incr;\r
1178                 ct.incr4 = CH->SLOT[SLOT4].Incr;\r
1179         }\r
1180 \r
1181         chan_render_loop(&ct, buffer, length);\r
1182 \r
1183         // write back persistent stuff:\r
1184         if (flags & 2) { /* last channel */\r
1185                 ym2612.OPN.eg_cnt = ct.eg_cnt;\r
1186                 ym2612.OPN.eg_timer = ct.eg_timer;\r
1187                 g_lfo_ampm = ct.pack >> 16;\r
1188                 ym2612.OPN.lfo_cnt = ct.lfo_cnt;\r
1189         }\r
1190 \r
1191         CH->op1_out = ct.op1_out;\r
1192         CH->SLOT[SLOT1].phase = ct.phase1;\r
1193         CH->SLOT[SLOT2].phase = ct.phase2;\r
1194         CH->SLOT[SLOT3].phase = ct.phase3;\r
1195         CH->SLOT[SLOT4].phase = ct.phase4;\r
1196         CH->mem_value = ct.mem;\r
1197 \r
1198         return (ct.algo & 8) >> 3; // had output\r
1199 }\r
1200 \r
1201 /* update phase increment and envelope generator */\r
1202 INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT, int fc, int kc)\r
1203 {\r
1204         int ksr;\r
1205 \r
1206         /* (frequency) phase increment counter */\r
1207         SLOT->Incr = ((fc+SLOT->DT[kc])*SLOT->mul) >> 1;\r
1208 \r
1209         ksr = kc >> SLOT->KSR;\r
1210         if( SLOT->ksr != ksr )\r
1211         {\r
1212                 int eg_sh, eg_sel;\r
1213                 SLOT->ksr = ksr;\r
1214 \r
1215                 /* calculate envelope generator rates */\r
1216                 if ((SLOT->ar + SLOT->ksr) < 32+62)\r
1217                 {\r
1218                         eg_sh  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];\r
1219                         eg_sel = eg_rate_select[SLOT->ar  + SLOT->ksr ];\r
1220                 }\r
1221                 else\r
1222                 {\r
1223                         eg_sh  = 0;\r
1224                         eg_sel = 17;\r
1225                 }\r
1226 \r
1227                 SLOT->eg_pack_ar = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1228 \r
1229                 eg_sh  = eg_rate_shift [SLOT->d1r + SLOT->ksr];\r
1230                 eg_sel = eg_rate_select[SLOT->d1r + SLOT->ksr];\r
1231 \r
1232                 SLOT->eg_pack_d1r = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1233 \r
1234                 eg_sh  = eg_rate_shift [SLOT->d2r + SLOT->ksr];\r
1235                 eg_sel = eg_rate_select[SLOT->d2r + SLOT->ksr];\r
1236 \r
1237                 SLOT->eg_pack_d2r = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1238 \r
1239                 eg_sh  = eg_rate_shift [SLOT->rr  + SLOT->ksr];\r
1240                 eg_sel = eg_rate_select[SLOT->rr  + SLOT->ksr];\r
1241 \r
1242                 SLOT->eg_pack_rr = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1243         }\r
1244 }\r
1245 \r
1246 /* update phase increment counters */\r
1247 INLINE void refresh_fc_eg_chan(FM_CH *CH)\r
1248 {\r
1249         if( CH->SLOT[SLOT1].Incr==-1){\r
1250                 int fc = CH->fc;\r
1251                 int kc = CH->kcode;\r
1252                 refresh_fc_eg_slot(&CH->SLOT[SLOT1] , fc , kc );\r
1253                 refresh_fc_eg_slot(&CH->SLOT[SLOT2] , fc , kc );\r
1254                 refresh_fc_eg_slot(&CH->SLOT[SLOT3] , fc , kc );\r
1255                 refresh_fc_eg_slot(&CH->SLOT[SLOT4] , fc , kc );\r
1256         }\r
1257 }\r
1258 \r
1259 /* initialize time tables */\r
1260 static void init_timetables(const UINT8 *dttable)\r
1261 {\r
1262         int i,d;\r
1263         double rate;\r
1264 \r
1265         /* DeTune table */\r
1266         for (d = 0;d <= 3;d++){\r
1267                 for (i = 0;i <= 31;i++){\r
1268                         rate = ((double)dttable[d*32 + i]) * SIN_LEN  * ym2612.OPN.ST.freqbase  * (1<<FREQ_SH) / ((double)(1<<20));\r
1269                         ym2612.OPN.ST.dt_tab[d][i]   = (INT32) rate;\r
1270                         ym2612.OPN.ST.dt_tab[d+4][i] = -ym2612.OPN.ST.dt_tab[d][i];\r
1271                 }\r
1272         }\r
1273 }\r
1274 \r
1275 \r
1276 static void reset_channels(FM_CH *CH, int num)\r
1277 {\r
1278         int c,s;\r
1279 \r
1280         ym2612.OPN.ST.mode   = 0;       /* normal mode */\r
1281         ym2612.OPN.ST.TA     = 0;\r
1282         ym2612.OPN.ST.TAC    = 0;\r
1283         ym2612.OPN.ST.TB     = 0;\r
1284         ym2612.OPN.ST.TBC    = 0;\r
1285 \r
1286         for( c = 0 ; c < num ; c++ )\r
1287         {\r
1288                 CH[c].fc = 0;\r
1289                 for(s = 0 ; s < 4 ; s++ )\r
1290                 {\r
1291                         CH[c].SLOT[s].state= EG_OFF;\r
1292                         CH[c].SLOT[s].volume = MAX_ATT_INDEX;\r
1293                 }\r
1294         }\r
1295 }\r
1296 \r
1297 /* initialize generic tables */\r
1298 static void init_tables(void)\r
1299 {\r
1300         signed int i,x,y,p;\r
1301         signed int n;\r
1302         double o,m;\r
1303 \r
1304         for (i=0; i < 256; i++)\r
1305         {\r
1306                 /* non-standard sinus */\r
1307                 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */\r
1308 \r
1309                 /* we never reach zero here due to ((i*2)+1) */\r
1310 \r
1311                 if (m>0.0)\r
1312                         o = 8*log(1.0/m)/log(2);        /* convert to 'decibels' */\r
1313                 else\r
1314                         o = 8*log(-1.0/m)/log(2);       /* convert to 'decibels' */\r
1315 \r
1316                 o = o / (ENV_STEP/4);\r
1317 \r
1318                 n = (int)(2.0*o);\r
1319                 if (n&1)                                                /* round to nearest */\r
1320                         n = (n>>1)+1;\r
1321                 else\r
1322                         n = n>>1;\r
1323 \r
1324                 ym_sin_tab[ i ] = n;\r
1325                 //dprintf("FM.C: sin [%4i]= %4i", i, ym_sin_tab[i]);\r
1326         }\r
1327 \r
1328         //dprintf("FM.C: ENV_QUIET= %08x", ENV_QUIET );\r
1329 \r
1330 \r
1331         for (x=0; x < TL_RES_LEN; x++)\r
1332         {\r
1333                 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);\r
1334                 m = floor(m);\r
1335 \r
1336                 /* we never reach (1<<16) here due to the (x+1) */\r
1337                 /* result fits within 16 bits at maximum */\r
1338 \r
1339                 n = (int)m;             /* 16 bits here */\r
1340                 n >>= 4;                /* 12 bits here */\r
1341                 if (n&1)                /* round to nearest */\r
1342                         n = (n>>1)+1;\r
1343                 else\r
1344                         n = n>>1;\r
1345                                                 /* 11 bits here (rounded) */\r
1346                 n <<= 2;                /* 13 bits here (as in real chip) */\r
1347                 ym_tl_tab2[ x ] = n;\r
1348 \r
1349                 for (i=1; i < 13; i++)\r
1350                 {\r
1351                         ym_tl_tab2[ x + i*TL_RES_LEN ] = n >> i;\r
1352                 }\r
1353         }\r
1354 \r
1355         for (x=0; x < 256; x++)\r
1356         {\r
1357                 int sin = ym_sin_tab[ x ];\r
1358 \r
1359                 for (y=0; y < 2*13*TL_RES_LEN/8; y+=2)\r
1360                 {\r
1361                         p = (y<<2) + sin;\r
1362                         if (p >= 13*TL_RES_LEN)\r
1363                                  ym_tl_tab[(y<<7) | x] = 0;\r
1364                         else ym_tl_tab[(y<<7) | x] = ym_tl_tab2[p];\r
1365                 }\r
1366         }\r
1367 \r
1368 \r
1369         /* build LFO PM modulation table */\r
1370         for(i = 0; i < 8; i++) /* 8 PM depths */\r
1371         {\r
1372                 UINT8 fnum;\r
1373                 for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */\r
1374                 {\r
1375                         UINT8 value;\r
1376                         UINT8 step;\r
1377                         UINT32 offset_depth = i;\r
1378                         UINT32 offset_fnum_bit;\r
1379                         UINT32 bit_tmp;\r
1380 \r
1381                         for (step=0; step<8; step++)\r
1382                         {\r
1383                                 value = 0;\r
1384                                 for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */\r
1385                                 {\r
1386                                         if (fnum & (1<<bit_tmp)) /* only if bit "bit_tmp" is set */\r
1387                                         {\r
1388                                                 offset_fnum_bit = bit_tmp * 8;\r
1389                                                 value += lfo_pm_output[offset_fnum_bit + offset_depth][step];\r
1390                                         }\r
1391                                 }\r
1392                                 lfo_pm_table[(fnum*32*8) + (i*32) + step   + 0] = value;\r
1393                                 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+ 8] = value;\r
1394                                 lfo_pm_table[(fnum*32*8) + (i*32) + step   +16] = -value;\r
1395                                 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+24] = -value;\r
1396                         }\r
1397                 }\r
1398         }\r
1399 }\r
1400 \r
1401 \r
1402 /* CSM Key Controll */\r
1403 INLINE void CSMKeyControll(FM_CH *CH)\r
1404 {\r
1405         /* this is wrong, atm */\r
1406 \r
1407         /* all key on */\r
1408         FM_KEYON(CH,SLOT1);\r
1409         FM_KEYON(CH,SLOT2);\r
1410         FM_KEYON(CH,SLOT3);\r
1411         FM_KEYON(CH,SLOT4);\r
1412 }\r
1413 \r
1414 \r
1415 /* prescaler set (and make time tables) */\r
1416 static void OPNSetPres(int pres)\r
1417 {\r
1418         int i;\r
1419 \r
1420         /* frequency base */\r
1421         ym2612.OPN.ST.freqbase = (ym2612.OPN.ST.rate) ? ((double)ym2612.OPN.ST.clock / ym2612.OPN.ST.rate) / pres : 0;\r
1422 \r
1423         ym2612.OPN.eg_timer_add  = (1<<EG_SH) * ym2612.OPN.ST.freqbase;\r
1424 \r
1425 \r
1426         /* make time tables */\r
1427         init_timetables( dt_tab );\r
1428 \r
1429         /* there are 2048 FNUMs that can be generated using FNUM/BLK registers\r
1430         but LFO works with one more bit of a precision so we really need 4096 elements */\r
1431         /* calculate fnumber -> increment counter table */\r
1432         for(i = 0; i < 4096; i++)\r
1433         {\r
1434                 /* freq table for octave 7 */\r
1435                 /* OPN phase increment counter = 20bit */\r
1436                 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
1437         }\r
1438 \r
1439         /* LFO freq. table */\r
1440         for(i = 0; i < 8; i++)\r
1441         {\r
1442                 /* Amplitude modulation: 64 output levels (triangle waveform); 1 level lasts for one of "lfo_samples_per_step" samples */\r
1443                 /* Phase modulation: one entry from lfo_pm_output lasts for one of 4 * "lfo_samples_per_step" samples  */\r
1444                 ym2612.OPN.lfo_freq[i] = (1.0 / lfo_samples_per_step[i]) * (1<<LFO_SH) * ym2612.OPN.ST.freqbase;\r
1445         }\r
1446 }\r
1447 \r
1448 \r
1449 /* write a OPN register (0x30-0xff) */\r
1450 static int OPNWriteReg(int r, int v)\r
1451 {\r
1452         int ret = 1;\r
1453         FM_CH *CH;\r
1454         FM_SLOT *SLOT;\r
1455 \r
1456         UINT8 c = OPN_CHAN(r);\r
1457 \r
1458         if (c == 3) return 0; /* 0xX3,0xX7,0xXB,0xXF */\r
1459 \r
1460         if (r >= 0x100) c+=3;\r
1461 \r
1462         CH = &ym2612.CH[c];\r
1463 \r
1464         SLOT = &(CH->SLOT[OPN_SLOT(r)]);\r
1465 \r
1466         switch( r & 0xf0 ) {\r
1467         case 0x30:      /* DET , MUL */\r
1468                 set_det_mul(CH,SLOT,v);\r
1469                 break;\r
1470 \r
1471         case 0x40:      /* TL */\r
1472                 set_tl(SLOT,v);\r
1473                 break;\r
1474 \r
1475         case 0x50:      /* KS, AR */\r
1476                 set_ar_ksr(CH,SLOT,v);\r
1477                 break;\r
1478 \r
1479         case 0x60:      /* bit7 = AM ENABLE, DR */\r
1480                 set_dr(SLOT,v);\r
1481                 if(v&0x80) CH->AMmasks |=   1<<OPN_SLOT(r);\r
1482                 else       CH->AMmasks &= ~(1<<OPN_SLOT(r));\r
1483                 break;\r
1484 \r
1485         case 0x70:      /*     SR */\r
1486                 set_sr(SLOT,v);\r
1487                 break;\r
1488 \r
1489         case 0x80:      /* SL, RR */\r
1490                 set_sl_rr(SLOT,v);\r
1491                 break;\r
1492 \r
1493         case 0x90:      /* SSG-EG */\r
1494                 // removed.\r
1495                 ret = 0;\r
1496                 break;\r
1497 \r
1498         case 0xa0:\r
1499                 switch( OPN_SLOT(r) ){\r
1500                 case 0:         /* 0xa0-0xa2 : FNUM1 */\r
1501                         {\r
1502                                 UINT32 fn = (((UINT32)( (ym2612.OPN.ST.fn_h)&7))<<8) + v;\r
1503                                 UINT8 blk = ym2612.OPN.ST.fn_h>>3;\r
1504                                 /* keyscale code */\r
1505                                 CH->kcode = (blk<<2) | opn_fktable[fn >> 7];\r
1506                                 /* phase increment counter */\r
1507                                 CH->fc = fn_table[fn*2]>>(7-blk);\r
1508 \r
1509                                 /* store fnum in clear form for LFO PM calculations */\r
1510                                 CH->block_fnum = (blk<<11) | fn;\r
1511 \r
1512                                 CH->SLOT[SLOT1].Incr=-1;\r
1513                         }\r
1514                         break;\r
1515                 case 1:         /* 0xa4-0xa6 : FNUM2,BLK */\r
1516                         ym2612.OPN.ST.fn_h = v&0x3f;\r
1517                         ret = 0;\r
1518                         break;\r
1519                 case 2:         /* 0xa8-0xaa : 3CH FNUM1 */\r
1520                         if(r < 0x100)\r
1521                         {\r
1522                                 UINT32 fn = (((UINT32)(ym2612.OPN.SL3.fn_h&7))<<8) + v;\r
1523                                 UINT8 blk = ym2612.OPN.SL3.fn_h>>3;\r
1524                                 /* keyscale code */\r
1525                                 ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];\r
1526                                 /* phase increment counter */\r
1527                                 ym2612.OPN.SL3.fc[c] = fn_table[fn*2]>>(7-blk);\r
1528                                 ym2612.OPN.SL3.block_fnum[c] = fn;\r
1529                                 ym2612.CH[2].SLOT[SLOT1].Incr=-1;\r
1530                         }\r
1531                         break;\r
1532                 case 3:         /* 0xac-0xae : 3CH FNUM2,BLK */\r
1533                         if(r < 0x100)\r
1534                                 ym2612.OPN.SL3.fn_h = v&0x3f;\r
1535                         ret = 0;\r
1536                         break;\r
1537                 default:\r
1538                         ret = 0;\r
1539                         break;\r
1540                 }\r
1541                 break;\r
1542 \r
1543         case 0xb0:\r
1544                 switch( OPN_SLOT(r) ){\r
1545                 case 0:         /* 0xb0-0xb2 : FB,ALGO */\r
1546                         {\r
1547                                 int feedback = (v>>3)&7;\r
1548                                 CH->ALGO = v&7;\r
1549                                 CH->FB   = feedback ? feedback+6 : 0;\r
1550                         }\r
1551                         break;\r
1552                 case 1:         /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */\r
1553                         {\r
1554                                 int panshift = c<<1;\r
1555 \r
1556                                 /* b0-2 PMS */\r
1557                                 CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */\r
1558 \r
1559                                 /* b4-5 AMS */\r
1560                                 CH->ams = lfo_ams_depth_shift[(v>>4) & 3];\r
1561 \r
1562                                 /* PAN :  b7 = L, b6 = R */\r
1563                                 ym2612.OPN.pan &= ~(3<<panshift);\r
1564                                 ym2612.OPN.pan |= ((v & 0xc0) >> 6) << panshift; // ..LRLR\r
1565                         }\r
1566                         break;\r
1567                 default:\r
1568                         ret = 0;\r
1569                         break;\r
1570                 }\r
1571                 break;\r
1572         default:\r
1573                 ret = 0;\r
1574                 break;\r
1575         }\r
1576 \r
1577         return ret;\r
1578 }\r
1579 \r
1580 \r
1581 /*******************************************************************************/\r
1582 /*      YM2612 local section                                                   */\r
1583 /*******************************************************************************/\r
1584 \r
1585 int   *ym2612_dacen;\r
1586 INT32 *ym2612_dacout;\r
1587 \r
1588 \r
1589 /* Generate samples for YM2612 */\r
1590 int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)\r
1591 {\r
1592         int pan;\r
1593         int active_chs = 0;\r
1594 \r
1595         // if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash\r
1596         if (is_buf_empty) memset32(buffer, 0, length<<stereo);\r
1597 \r
1598         /* refresh PG and EG */\r
1599         refresh_fc_eg_chan( &ym2612.CH[0] );\r
1600         refresh_fc_eg_chan( &ym2612.CH[1] );\r
1601         if( (ym2612.OPN.ST.mode & 0xc0) )\r
1602         {\r
1603                 /* 3SLOT MODE */\r
1604                 if( ym2612.CH[2].SLOT[SLOT1].Incr==-1)\r
1605                 {\r
1606                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT1], ym2612.OPN.SL3.fc[1], ym2612.OPN.SL3.kcode[1] );\r
1607                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT2], ym2612.OPN.SL3.fc[2], ym2612.OPN.SL3.kcode[2] );\r
1608                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT3], ym2612.OPN.SL3.fc[0], ym2612.OPN.SL3.kcode[0] );\r
1609                         refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT4], ym2612.CH[2].fc , ym2612.CH[2].kcode );\r
1610                 }\r
1611         } else refresh_fc_eg_chan( &ym2612.CH[2] );\r
1612         refresh_fc_eg_chan( &ym2612.CH[3] );\r
1613         refresh_fc_eg_chan( &ym2612.CH[4] );\r
1614         refresh_fc_eg_chan( &ym2612.CH[5] );\r
1615 \r
1616         pan = ym2612.OPN.pan;\r
1617         if (stereo) stereo = 1;\r
1618 \r
1619         /* mix to 32bit dest */\r
1620         // flags: stereo, lastchan, disabled, ?, pan_r, pan_l\r
1621         active_chs |= chan_render(buffer, length, &ym2612.CH[0], stereo|((pan&0x003)<<4)) << 0;\r
1622         active_chs |= chan_render(buffer, length, &ym2612.CH[1], stereo|((pan&0x00c)<<2)) << 1;\r
1623         active_chs |= chan_render(buffer, length, &ym2612.CH[2], stereo|((pan&0x030)   )) << 2;\r
1624         active_chs |= chan_render(buffer, length, &ym2612.CH[3], stereo|((pan&0x0c0)>>2)) << 3;\r
1625         active_chs |= chan_render(buffer, length, &ym2612.CH[4], stereo|((pan&0x300)>>4)) << 4;\r
1626         active_chs |= chan_render(buffer, length, &ym2612.CH[5], stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)|2) << 5;\r
1627 \r
1628         return active_chs; // 1 if buffer updated\r
1629 }\r
1630 \r
1631 \r
1632 /* initialize YM2612 emulator */\r
1633 void YM2612Init_(int clock, int rate)\r
1634 {\r
1635         // notaz\r
1636         ym2612_dacen = &ym2612.dacen;\r
1637         ym2612_dacout = &ym2612.dacout;\r
1638 \r
1639         /* clear everything but the regs */\r
1640         memset(ym2612.CH, 0, sizeof(ym2612)-sizeof(ym2612.REGS)-4);\r
1641         init_tables();\r
1642 \r
1643         ym2612.OPN.ST.clock = clock;\r
1644         ym2612.OPN.ST.rate = rate;\r
1645 \r
1646         /* Extend handler */\r
1647         YM2612ResetChip_();\r
1648 }\r
1649 \r
1650 \r
1651 /* reset */\r
1652 void YM2612ResetChip_(void)\r
1653 {\r
1654         int i;\r
1655 \r
1656         OPNSetPres( 6*24 );\r
1657         set_timers( 0x30 ); /* mode 0 , timer reset */\r
1658 \r
1659         ym2612.OPN.eg_timer = 0;\r
1660         ym2612.OPN.eg_cnt   = 0;\r
1661         ym2612.OPN.ST.status = 0;\r
1662 \r
1663         reset_channels( &ym2612.CH[0] , 6 );\r
1664         for(i = 0xb6 ; i >= 0xb4 ; i-- )\r
1665         {\r
1666                 OPNWriteReg(i      ,0xc0);\r
1667                 OPNWriteReg(i|0x100,0xc0);\r
1668         }\r
1669         for(i = 0xb2 ; i >= 0x30 ; i-- )\r
1670         {\r
1671                 OPNWriteReg(i      ,0);\r
1672                 OPNWriteReg(i|0x100,0);\r
1673         }\r
1674         for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0);\r
1675         /* DAC mode clear */\r
1676         ym2612.dacen = 0;\r
1677 }\r
1678 \r
1679 \r
1680 /* YM2612 write */\r
1681 /* a = address */\r
1682 /* v = value   */\r
1683 /* returns 1 if sample affecting state changed */\r
1684 int YM2612Write_(unsigned int a, unsigned int v)\r
1685 {\r
1686         int addr, ret=1;\r
1687 \r
1688         v &= 0xff;      /* adjust to 8 bit bus */\r
1689 \r
1690         switch( a&3){\r
1691         case 0: /* address port 0 */\r
1692                 ym2612.OPN.ST.address = v;\r
1693                 ym2612.addr_A1 = 0;\r
1694                 ret=0;\r
1695                 break;\r
1696 \r
1697         case 1: /* data port 0    */\r
1698                 if (ym2612.addr_A1 != 0) {\r
1699                         ret=0;\r
1700                         break;  /* verified on real YM2608 */\r
1701                 }\r
1702 \r
1703                 addr = ym2612.OPN.ST.address;\r
1704                 ym2612.REGS[addr] = v;\r
1705 \r
1706                 switch( addr & 0xf0 )\r
1707                 {\r
1708                 case 0x20:      /* 0x20-0x2f Mode */\r
1709                         switch( addr )\r
1710                         {\r
1711                         case 0x22:      /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */\r
1712                                 if (v&0x08) /* LFO enabled ? */\r
1713                                 {\r
1714                                         ym2612.OPN.lfo_inc = ym2612.OPN.lfo_freq[v&7];\r
1715                                 }\r
1716                                 else\r
1717                                 {\r
1718                                         ym2612.OPN.lfo_inc = 0;\r
1719                                 }\r
1720                                 break;\r
1721                         case 0x24: { // timer A High 8\r
1722                                         int TAnew = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2);\r
1723                                         if(ym2612.OPN.ST.TA != TAnew) {\r
1724                                                 // we should reset ticker only if new value is written. Outrun requires this.\r
1725                                                 ym2612.OPN.ST.TA = TAnew;\r
1726                                                 ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
1727                                                 ym2612.OPN.ST.TAT = 0;\r
1728                                         }\r
1729                                 }\r
1730                                 ret=0;\r
1731                                 break;\r
1732                         case 0x25: { // timer A Low 2\r
1733                                         int TAnew = (ym2612.OPN.ST.TA & 0x3fc)|(v&3);\r
1734                                         if(ym2612.OPN.ST.TA != TAnew) {\r
1735                                                 ym2612.OPN.ST.TA = TAnew;\r
1736                                                 ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
1737                                                 ym2612.OPN.ST.TAT = 0;\r
1738                                         }\r
1739                                 }\r
1740                                 ret=0;\r
1741                                 break;\r
1742                         case 0x26: // timer B\r
1743                                 if(ym2612.OPN.ST.TB != v) {\r
1744                                         ym2612.OPN.ST.TB = v;\r
1745                                         ym2612.OPN.ST.TBC  = (256-v)<<4;\r
1746                                         ym2612.OPN.ST.TBC *= 18;\r
1747                                         ym2612.OPN.ST.TBT  = 0;\r
1748                                 }\r
1749                                 ret=0;\r
1750                                 break;\r
1751                         case 0x27:      /* mode, timer control */\r
1752                                 set_timers( v );\r
1753                                 ret=0;\r
1754                                 break;\r
1755                         case 0x28:      /* key on / off */\r
1756                                 {\r
1757                                         UINT8 c;\r
1758                                         FM_CH *CH;\r
1759 \r
1760                                         c = v & 0x03;\r
1761                                         if( c == 3 ) { ret=0; break; }\r
1762                                         if( v&0x04 ) c+=3;\r
1763                                         CH = &ym2612.CH[c];\r
1764                                         if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);\r
1765                                         if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);\r
1766                                         if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);\r
1767                                         if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);\r
1768                                         break;\r
1769                                 }\r
1770                         case 0x2a:      /* DAC data (YM2612) */\r
1771                                 ym2612.dacout = ((int)v - 0x80) << 6;   /* level unknown (notaz: 8 seems to be too much) */\r
1772                                 ret=0;\r
1773                                 break;\r
1774                         case 0x2b:      /* DAC Sel  (YM2612) */\r
1775                                 /* b7 = dac enable */\r
1776                                 ym2612.dacen = v & 0x80;\r
1777                                 ret=0;\r
1778                                 break;\r
1779                         default:\r
1780                                 break;\r
1781                         }\r
1782                         break;\r
1783                 default:        /* 0x30-0xff OPN section */\r
1784                         /* write register */\r
1785                         ret = OPNWriteReg(addr,v);\r
1786                 }\r
1787                 break;\r
1788 \r
1789         case 2: /* address port 1 */\r
1790                 ym2612.OPN.ST.address = v;\r
1791                 ym2612.addr_A1 = 1;\r
1792                 ret=0;\r
1793                 break;\r
1794 \r
1795         case 3: /* data port 1    */\r
1796                 if (ym2612.addr_A1 != 1) {\r
1797                         ret=0;\r
1798                         break;  /* verified on real YM2608 */\r
1799                 }\r
1800 \r
1801                 addr = ym2612.OPN.ST.address | 0x100;\r
1802                 ym2612.REGS[addr] = v;\r
1803 \r
1804                 ret = OPNWriteReg(addr, v);\r
1805                 break;\r
1806         }\r
1807 /*\r
1808         if(ret) {\r
1809                 extern int Scanline;\r
1810                 dprintf("ymw [%i]", Scanline);\r
1811         }\r
1812 */\r
1813         return ret;\r
1814 }\r
1815 \r
1816 UINT8 YM2612Read_(void)\r
1817 {\r
1818         return ym2612.OPN.ST.status;\r
1819 }\r
1820 \r
1821 \r
1822 int YM2612PicoTick_(int n)\r
1823 {\r
1824         int ret = 0;\r
1825 \r
1826         // timer A\r
1827         if(ym2612.OPN.ST.mode & 0x01 && (ym2612.OPN.ST.TAT+=64*n) >= ym2612.OPN.ST.TAC) {\r
1828                 ym2612.OPN.ST.TAT -= ym2612.OPN.ST.TAC;\r
1829                 if(ym2612.OPN.ST.mode & 0x04) ym2612.OPN.ST.status |= 1;\r
1830                 // CSM mode total level latch and auto key on\r
1831                 if(ym2612.OPN.ST.mode & 0x80) {\r
1832                         CSMKeyControll( &(ym2612.CH[2]) ); // Vectorman2, etc.\r
1833                         ret = 1;\r
1834                 }\r
1835         }\r
1836 \r
1837         // timer B\r
1838         if(ym2612.OPN.ST.mode & 0x02 && (ym2612.OPN.ST.TBT+=64*n) >= ym2612.OPN.ST.TBC) {\r
1839                 ym2612.OPN.ST.TBT -= ym2612.OPN.ST.TBC;\r
1840                 if(ym2612.OPN.ST.mode & 0x08) ym2612.OPN.ST.status |= 2;\r
1841         }\r
1842 \r
1843         return ret;\r
1844 }\r
1845 \r
1846 \r
1847 void YM2612PicoStateLoad_(void)\r
1848 {\r
1849 #ifndef EXTERNAL_YM2612\r
1850         int i, old_A1 = ym2612.addr_A1;\r
1851 \r
1852         reset_channels( &ym2612.CH[0], 6 );\r
1853 \r
1854         // feed all the registers and update internal state\r
1855         for(i = 0; i < 0x100; i++) {\r
1856                 YM2612Write_(0, i);\r
1857                 YM2612Write_(1, ym2612.REGS[i]);\r
1858         }\r
1859         for(i = 0; i < 0x100; i++) {\r
1860                 YM2612Write_(2, i);\r
1861                 YM2612Write_(3, ym2612.REGS[i|0x100]);\r
1862         }\r
1863 \r
1864         ym2612.addr_A1 = old_A1;\r
1865 #else\r
1866         reset_channels( &ym2612.CH[0], 6 );\r
1867 #endif\r
1868 }\r
1869 \r
1870 \r
1871 void *YM2612GetRegs(void)\r
1872 {\r
1873         return ym2612.REGS;\r
1874 }\r