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