lowercasing filenames, part3
[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 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(int c , int s )\r
557 {\r
558         FM_SLOT *SLOT = &ym2612.CH[c].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                 SLOT->volume = MAX_ATT_INDEX;    /* fix Ecco 2 splash sound */\r
565                 ym2612.slot_mask |= (1<<s) << (c*4);\r
566         }\r
567 }\r
568 \r
569 INLINE void FM_KEYOFF(int c , int s )\r
570 {\r
571         FM_SLOT *SLOT = &ym2612.CH[c].SLOT[s];\r
572         if( SLOT->key )\r
573         {\r
574                 SLOT->key = 0;\r
575                 if (SLOT->state>EG_REL)\r
576                         SLOT->state = EG_REL;/* phase -> Release */\r
577         }\r
578 }\r
579 \r
580 \r
581 /* set detune & multiple */\r
582 INLINE void set_det_mul(FM_CH *CH, FM_SLOT *SLOT, int v)\r
583 {\r
584         SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1;\r
585         SLOT->DT  = ym2612.OPN.ST.dt_tab[(v>>4)&7];\r
586         CH->SLOT[SLOT1].Incr=-1;\r
587 }\r
588 \r
589 /* set total level */\r
590 INLINE void set_tl(FM_SLOT *SLOT, int v)\r
591 {\r
592         SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */\r
593 }\r
594 \r
595 /* set attack rate & key scale  */\r
596 INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)\r
597 {\r
598         UINT8 old_KSR = SLOT->KSR;\r
599 \r
600         SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
601 \r
602         SLOT->KSR = 3-(v>>6);\r
603         if (SLOT->KSR != old_KSR)\r
604         {\r
605                 CH->SLOT[SLOT1].Incr=-1;\r
606         }\r
607         else\r
608         {\r
609                 int eg_sh_ar, eg_sel_ar;\r
610 \r
611                 /* refresh Attack rate */\r
612                 if ((SLOT->ar + SLOT->ksr) < 32+62)\r
613                 {\r
614                         eg_sh_ar  = eg_rate_shift [SLOT->ar  + SLOT->ksr ];\r
615                         eg_sel_ar = eg_rate_select[SLOT->ar  + SLOT->ksr ];\r
616                 }\r
617                 else\r
618                 {\r
619                         eg_sh_ar  = 0;\r
620                         eg_sel_ar = 17;\r
621                 }\r
622 \r
623                 SLOT->eg_pack_ar = eg_inc_pack[eg_sel_ar] | (eg_sh_ar<<24);\r
624         }\r
625 }\r
626 \r
627 /* set decay rate */\r
628 INLINE void set_dr(FM_SLOT *SLOT, int v)\r
629 {\r
630         int eg_sh_d1r, eg_sel_d1r;\r
631 \r
632         SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
633 \r
634         eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];\r
635         eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];\r
636 \r
637         SLOT->eg_pack_d1r = eg_inc_pack[eg_sel_d1r] | (eg_sh_d1r<<24);\r
638 }\r
639 \r
640 /* set sustain rate */\r
641 INLINE void set_sr(FM_SLOT *SLOT, int v)\r
642 {\r
643         int eg_sh_d2r, eg_sel_d2r;\r
644 \r
645         SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;\r
646 \r
647         eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];\r
648         eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];\r
649 \r
650         SLOT->eg_pack_d2r = eg_inc_pack[eg_sel_d2r] | (eg_sh_d2r<<24);\r
651 }\r
652 \r
653 /* set release rate */\r
654 INLINE void set_sl_rr(FM_SLOT *SLOT, int v)\r
655 {\r
656         int eg_sh_rr, eg_sel_rr;\r
657 \r
658         SLOT->sl = sl_table[ v>>4 ];\r
659 \r
660         SLOT->rr  = 34 + ((v&0x0f)<<2);\r
661 \r
662         eg_sh_rr  = eg_rate_shift [SLOT->rr  + SLOT->ksr];\r
663         eg_sel_rr = eg_rate_select[SLOT->rr  + SLOT->ksr];\r
664 \r
665         SLOT->eg_pack_rr = eg_inc_pack[eg_sel_rr] | (eg_sh_rr<<24);\r
666 }\r
667 \r
668 \r
669 \r
670 INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm)\r
671 {\r
672         int ret, sin = (phase>>16) + (pm>>1);\r
673         int neg = sin & 0x200;\r
674         if (sin & 0x100) sin ^= 0xff;\r
675         sin&=0xff;\r
676         env&=~1;\r
677 \r
678         // this was already checked\r
679         // if (env >= ENV_QUIET) // 384\r
680         //      return 0;\r
681 \r
682         ret = ym_tl_tab[sin | (env<<7)];\r
683 \r
684         return neg ? -ret : ret;\r
685 }\r
686 \r
687 INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm)\r
688 {\r
689         int ret, sin = (phase+pm)>>16;\r
690         int neg = sin & 0x200;\r
691         if (sin & 0x100) sin ^= 0xff;\r
692         sin&=0xff;\r
693         env&=~1;\r
694 \r
695         // if (env >= ENV_QUIET) // 384\r
696         //      return 0;\r
697 \r
698         ret = ym_tl_tab[sin | (env<<7)];\r
699 \r
700         return neg ? -ret : ret;\r
701 }\r
702 \r
703 #if !defined(_ASM_YM2612_C) || defined(EXTERNAL_YM2612)\r
704 /* advance LFO to next sample */\r
705 INLINE int advance_lfo(int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt)\r
706 {\r
707         UINT8 pos;\r
708         UINT8 prev_pos;\r
709 \r
710         prev_pos = (lfo_cnt_old >> LFO_SH) & 127;\r
711 \r
712         pos = (lfo_cnt >> LFO_SH) & 127;\r
713 \r
714         /* update AM when LFO output changes */\r
715 \r
716         if (prev_pos != pos)\r
717         {\r
718                 lfo_ampm &= 0xff;\r
719                 /* triangle */\r
720                 /* AM: 0 to 126 step +2, 126 to 0 step -2 */\r
721                 if (pos<64)\r
722                         lfo_ampm |= ((pos&63) * 2) << 8;           /* 0 - 126 */\r
723                 else\r
724                         lfo_ampm |= (126 - (pos&63)*2) << 8;\r
725         }\r
726         else\r
727         {\r
728                 return lfo_ampm;\r
729         }\r
730 \r
731         /* PM works with 4 times slower clock */\r
732         prev_pos >>= 2;\r
733         pos >>= 2;\r
734         /* update PM when LFO output changes */\r
735         if (prev_pos != pos)\r
736         {\r
737                 lfo_ampm &= ~0xff;\r
738                 lfo_ampm |= pos; /* 0 - 32 */\r
739         }\r
740         return lfo_ampm;\r
741 }\r
742 \r
743 #define EG_INC_VAL() \\r
744         ((1 << ((pack >> ((eg_cnt>>shift)&7)*3)&7)) >> 1)\r
745 \r
746 INLINE UINT32 update_eg_phase(FM_SLOT *SLOT, UINT32 eg_cnt)\r
747 {\r
748         INT32 volume = SLOT->volume;\r
749 \r
750         switch(SLOT->state)\r
751         {\r
752                 case EG_ATT:            /* attack phase */\r
753                 {\r
754                         UINT32 pack = SLOT->eg_pack_ar;\r
755                         UINT32 shift = pack>>24;\r
756                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
757                         {\r
758                                 volume += ( ~volume * EG_INC_VAL() ) >>4;\r
759 \r
760                                 if (volume <= MIN_ATT_INDEX)\r
761                                 {\r
762                                         volume = MIN_ATT_INDEX;\r
763                                         SLOT->state = EG_DEC;\r
764                                 }\r
765                         }\r
766                         break;\r
767                 }\r
768 \r
769                 case EG_DEC:    /* decay phase */\r
770                 {\r
771                         UINT32 pack = SLOT->eg_pack_d1r;\r
772                         UINT32 shift = pack>>24;\r
773                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
774                         {\r
775                                 volume += EG_INC_VAL();\r
776 \r
777                                 if ( volume >= (INT32) SLOT->sl )\r
778                                         SLOT->state = EG_SUS;\r
779                         }\r
780                         break;\r
781                 }\r
782 \r
783                 case EG_SUS:    /* sustain phase */\r
784                 {\r
785                         UINT32 pack = SLOT->eg_pack_d2r;\r
786                         UINT32 shift = pack>>24;\r
787                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
788                         {\r
789                                 volume += EG_INC_VAL();\r
790 \r
791                                 if ( volume >= MAX_ATT_INDEX )\r
792                                 {\r
793                                         volume = MAX_ATT_INDEX;\r
794                                         /* do not change SLOT->state (verified on real chip) */\r
795                                 }\r
796                         }\r
797                         break;\r
798                 }\r
799 \r
800                 case EG_REL:    /* release phase */\r
801                 {\r
802                         UINT32 pack = SLOT->eg_pack_rr;\r
803                         UINT32 shift = pack>>24;\r
804                         if ( !(eg_cnt & ((1<<shift)-1) ) )\r
805                         {\r
806                                 volume += EG_INC_VAL();\r
807 \r
808                                 if ( volume >= MAX_ATT_INDEX )\r
809                                 {\r
810                                         volume = MAX_ATT_INDEX;\r
811                                         SLOT->state = EG_OFF;\r
812                                 }\r
813                         }\r
814                         break;\r
815                 }\r
816         }\r
817 \r
818         SLOT->volume = volume;\r
819         return SLOT->tl + ((UINT32)volume); /* tl is 7bit<<3, volume 0-1023 (0-2039 total) */\r
820 }\r
821 #endif\r
822 \r
823 \r
824 typedef struct\r
825 {\r
826         UINT16 vol_out1; /* 00: current output from EG circuit (without AM from LFO) */\r
827         UINT16 vol_out2;\r
828         UINT16 vol_out3;\r
829         UINT16 vol_out4;\r
830         UINT32 pad[2];\r
831         UINT32 phase1;   /* 10 */\r
832         UINT32 phase2;\r
833         UINT32 phase3;\r
834         UINT32 phase4;\r
835         UINT32 incr1;    /* 20: phase step */\r
836         UINT32 incr2;\r
837         UINT32 incr3;\r
838         UINT32 incr4;\r
839         UINT32 lfo_cnt;  /* 30 */\r
840         UINT32 lfo_inc;\r
841         INT32  mem;      /* one sample delay memory */\r
842         UINT32 eg_cnt;   /* envelope generator counter */\r
843         FM_CH  *CH;      /* 40: envelope generator counter */\r
844         UINT32 eg_timer;\r
845         UINT32 eg_timer_add;\r
846         UINT32 pack;     // 4c: stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16]\r
847         UINT32 algo;     /* 50: algo[3], was_update */\r
848         INT32  op1_out;\r
849 #ifdef _MIPS_ARCH_ALLEGREX\r
850         UINT32 pad1[3+8];\r
851 #endif\r
852 } chan_rend_context;\r
853 \r
854 \r
855 #if !defined(_ASM_YM2612_C) || defined(EXTERNAL_YM2612)\r
856 static void chan_render_loop(chan_rend_context *ct, int *buffer, int length)\r
857 {\r
858         int scounter;                                   /* sample counter */\r
859 \r
860         /* sample generating loop */\r
861         for (scounter = 0; scounter < length; scounter++)\r
862         {\r
863                 int smp = 0;            /* produced sample */\r
864                 unsigned int eg_out, eg_out2, eg_out4;\r
865 \r
866                 if (ct->pack & 8) { /* LFO enabled ? (test Earthworm Jim in between demo 1 and 2) */\r
867                         ct->pack = (ct->pack&0xffff) | (advance_lfo(ct->pack >> 16, ct->lfo_cnt, ct->lfo_cnt + ct->lfo_inc) << 16);\r
868                         ct->lfo_cnt += ct->lfo_inc;\r
869                 }\r
870 \r
871                 ct->eg_timer += ct->eg_timer_add;\r
872                 while (ct->eg_timer >= EG_TIMER_OVERFLOW)\r
873                 {\r
874                         ct->eg_timer -= EG_TIMER_OVERFLOW;\r
875                         ct->eg_cnt++;\r
876 \r
877                         if (ct->CH->SLOT[SLOT1].state != EG_OFF) ct->vol_out1 = update_eg_phase(&ct->CH->SLOT[SLOT1], ct->eg_cnt);\r
878                         if (ct->CH->SLOT[SLOT2].state != EG_OFF) ct->vol_out2 = update_eg_phase(&ct->CH->SLOT[SLOT2], ct->eg_cnt);\r
879                         if (ct->CH->SLOT[SLOT3].state != EG_OFF) ct->vol_out3 = update_eg_phase(&ct->CH->SLOT[SLOT3], ct->eg_cnt);\r
880                         if (ct->CH->SLOT[SLOT4].state != EG_OFF) ct->vol_out4 = update_eg_phase(&ct->CH->SLOT[SLOT4], ct->eg_cnt);\r
881                 }\r
882 \r
883                 if (ct->pack & 4) continue; /* output disabled */\r
884 \r
885                 /* calculate channel sample */\r
886                 eg_out = ct->vol_out1;\r
887                 if ( (ct->pack & 8) && (ct->pack&(1<<(SLOT1+8))) ) eg_out += ct->pack >> (((ct->pack&0xc0)>>6)+24);\r
888 \r
889                 if( eg_out < ENV_QUIET )        /* SLOT 1 */\r
890                 {\r
891                         int out = 0;\r
892 \r
893                         if (ct->pack&0xf000) out = ((ct->op1_out>>16) + ((ct->op1_out<<16)>>16)) << ((ct->pack&0xf000)>>12); /* op1_out0 + op1_out1 */\r
894                         ct->op1_out <<= 16;\r
895                         ct->op1_out |= (unsigned short)op_calc1(ct->phase1, eg_out, out);\r
896                 } else {\r
897                         ct->op1_out <<= 16; /* op1_out0 = op1_out1; op1_out1 = 0; */\r
898                 }\r
899 \r
900                 eg_out  = ct->vol_out3; // volume_calc(&CH->SLOT[SLOT3]);\r
901                 eg_out2 = ct->vol_out2; // volume_calc(&CH->SLOT[SLOT2]);\r
902                 eg_out4 = ct->vol_out4; // volume_calc(&CH->SLOT[SLOT4]);\r
903 \r
904                 if (ct->pack & 8) {\r
905                         unsigned int add = ct->pack >> (((ct->pack&0xc0)>>6)+24);\r
906                         if (ct->pack & (1<<(SLOT3+8))) eg_out  += add;\r
907                         if (ct->pack & (1<<(SLOT2+8))) eg_out2 += add;\r
908                         if (ct->pack & (1<<(SLOT4+8))) eg_out4 += add;\r
909                 }\r
910 \r
911                 switch( ct->CH->ALGO )\r
912                 {\r
913                         case 0:\r
914                         {\r
915                                 /* M1---C1---MEM---M2---C2---OUT */\r
916                                 int m2,c1,c2=0; /* Phase Modulation input for operators 2,3,4 */\r
917                                 m2 = ct->mem;\r
918                                 c1 = ct->op1_out>>16;\r
919                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
920                                         c2  = op_calc(ct->phase3, eg_out,  m2);\r
921                                 }\r
922                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
923                                         ct->mem = op_calc(ct->phase2, eg_out2, c1);\r
924                                 }\r
925                                 else ct->mem = 0;\r
926                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
927                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
928                                 }\r
929                                 break;\r
930                         }\r
931                         case 1:\r
932                         {\r
933                                 /* M1------+-MEM---M2---C2---OUT */\r
934                                 /*      C1-+                     */\r
935                                 int m2,c2=0;\r
936                                 m2 = ct->mem;\r
937                                 ct->mem = ct->op1_out>>16;\r
938                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
939                                         c2  = op_calc(ct->phase3, eg_out,  m2);\r
940                                 }\r
941                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
942                                         ct->mem+= op_calc(ct->phase2, eg_out2, 0);\r
943                                 }\r
944                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
945                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
946                                 }\r
947                                 break;\r
948                         }\r
949                         case 2:\r
950                         {\r
951                                 /* M1-----------------+-C2---OUT */\r
952                                 /*      C1---MEM---M2-+          */\r
953                                 int m2,c2;\r
954                                 m2 = ct->mem;\r
955                                 c2 = ct->op1_out>>16;\r
956                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
957                                         c2 += op_calc(ct->phase3, eg_out,  m2);\r
958                                 }\r
959                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
960                                         ct->mem = op_calc(ct->phase2, eg_out2, 0);\r
961                                 }\r
962                                 else ct->mem = 0;\r
963                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
964                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
965                                 }\r
966                                 break;\r
967                         }\r
968                         case 3:\r
969                         {\r
970                                 /* M1---C1---MEM------+-C2---OUT */\r
971                                 /*                 M2-+          */\r
972                                 int c1,c2;\r
973                                 c2 = ct->mem;\r
974                                 c1 = ct->op1_out>>16;\r
975                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
976                                         c2 += op_calc(ct->phase3, eg_out,  0);\r
977                                 }\r
978                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
979                                         ct->mem = op_calc(ct->phase2, eg_out2, c1);\r
980                                 }\r
981                                 else ct->mem = 0;\r
982                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
983                                         smp = op_calc(ct->phase4, eg_out4, c2);\r
984                                 }\r
985                                 break;\r
986                         }\r
987                         case 4:\r
988                         {\r
989                                 /* M1---C1-+-OUT */\r
990                                 /* M2---C2-+     */\r
991                                 /* MEM: not used */\r
992                                 int c1,c2=0;\r
993                                 c1 = ct->op1_out>>16;\r
994                                 if( eg_out  < ENV_QUIET ) {             /* SLOT 3 */\r
995                                         c2  = op_calc(ct->phase3, eg_out,  0);\r
996                                 }\r
997                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
998                                         smp = op_calc(ct->phase2, eg_out2, c1);\r
999                                 }\r
1000                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1001                                         smp+= op_calc(ct->phase4, eg_out4, c2);\r
1002                                 }\r
1003                                 break;\r
1004                         }\r
1005                         case 5:\r
1006                         {\r
1007                                 /*    +----C1----+     */\r
1008                                 /* M1-+-MEM---M2-+-OUT */\r
1009                                 /*    +----C2----+     */\r
1010                                 int m2,c1,c2;\r
1011                                 m2 = ct->mem;\r
1012                                 ct->mem = c1 = c2 = ct->op1_out>>16;\r
1013                                 if( eg_out < ENV_QUIET ) {              /* SLOT 3 */\r
1014                                         smp = op_calc(ct->phase3, eg_out, m2);\r
1015                                 }\r
1016                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1017                                         smp+= op_calc(ct->phase2, eg_out2, c1);\r
1018                                 }\r
1019                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1020                                         smp+= op_calc(ct->phase4, eg_out4, c2);\r
1021                                 }\r
1022                                 break;\r
1023                         }\r
1024                         case 6:\r
1025                         {\r
1026                                 /* M1---C1-+     */\r
1027                                 /*      M2-+-OUT */\r
1028                                 /*      C2-+     */\r
1029                                 /* MEM: not used */\r
1030                                 int c1;\r
1031                                 c1 = ct->op1_out>>16;\r
1032                                 if( eg_out < ENV_QUIET ) {              /* SLOT 3 */\r
1033                                         smp = op_calc(ct->phase3, eg_out,  0);\r
1034                                 }\r
1035                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1036                                         smp+= op_calc(ct->phase2, eg_out2, c1);\r
1037                                 }\r
1038                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1039                                         smp+= op_calc(ct->phase4, eg_out4, 0);\r
1040                                 }\r
1041                                 break;\r
1042                         }\r
1043                         case 7:\r
1044                         {\r
1045                                 /* M1-+     */\r
1046                                 /* C1-+-OUT */\r
1047                                 /* M2-+     */\r
1048                                 /* C2-+     */\r
1049                                 /* MEM: not used*/\r
1050                                 smp = ct->op1_out>>16;\r
1051                                 if( eg_out < ENV_QUIET ) {              /* SLOT 3 */\r
1052                                         smp += op_calc(ct->phase3, eg_out,  0);\r
1053                                 }\r
1054                                 if( eg_out2 < ENV_QUIET ) {             /* SLOT 2 */\r
1055                                         smp += op_calc(ct->phase2, eg_out2, 0);\r
1056                                 }\r
1057                                 if( eg_out4 < ENV_QUIET ) {             /* SLOT 4 */\r
1058                                         smp += op_calc(ct->phase4, eg_out4, 0);\r
1059                                 }\r
1060                                 break;\r
1061                         }\r
1062                 }\r
1063                 /* done calculating channel sample */\r
1064 \r
1065                 /* mix sample to output buffer */\r
1066                 if (smp) {\r
1067                         if (ct->pack & 1) { /* stereo */\r
1068                                 if (ct->pack & 0x20) /* L */ /* TODO: check correctness */\r
1069                                         buffer[scounter*2] += smp;\r
1070                                 if (ct->pack & 0x10) /* R */\r
1071                                         buffer[scounter*2+1] += smp;\r
1072                         } else {\r
1073                                 buffer[scounter] += smp;\r
1074                         }\r
1075                         ct->algo = 8; // algo is only used in asm, here only bit3 is used\r
1076                 }\r
1077 \r
1078                 /* update phase counters AFTER output calculations */\r
1079                 ct->phase1 += ct->incr1;\r
1080                 ct->phase2 += ct->incr2;\r
1081                 ct->phase3 += ct->incr3;\r
1082                 ct->phase4 += ct->incr4;\r
1083         }\r
1084 }\r
1085 #else\r
1086 void chan_render_loop(chan_rend_context *ct, int *buffer, unsigned short length);\r
1087 #endif\r
1088 \r
1089 static chan_rend_context crct;\r
1090 \r
1091 static void chan_render_prep(void)\r
1092 {\r
1093         crct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
1094         crct.lfo_inc = ym2612.OPN.lfo_inc;\r
1095 }\r
1096 \r
1097 static void chan_render_finish(void)\r
1098 {\r
1099         ym2612.OPN.eg_cnt = crct.eg_cnt;\r
1100         ym2612.OPN.eg_timer = crct.eg_timer;\r
1101         g_lfo_ampm = crct.pack >> 16; // need_save\r
1102         ym2612.OPN.lfo_cnt = crct.lfo_cnt;\r
1103 }\r
1104 \r
1105 static int chan_render(int *buffer, int length, int c, UINT32 flags) // flags: stereo, ?, disabled, ?, pan_r, pan_l\r
1106 {\r
1107         crct.CH = &ym2612.CH[c];\r
1108         crct.mem = crct.CH->mem_value;          /* one sample delay memory */\r
1109         crct.lfo_cnt = ym2612.OPN.lfo_cnt;\r
1110 \r
1111         flags &= 0x35;\r
1112 \r
1113         if (crct.lfo_inc) {\r
1114                 flags |= 8;\r
1115                 flags |= g_lfo_ampm << 16;\r
1116                 flags |= crct.CH->AMmasks << 8;\r
1117                 if (crct.CH->ams == 8) // no ams\r
1118                      flags &= ~0xf00;\r
1119                 else flags |= (crct.CH->ams&3)<<6;\r
1120         }\r
1121         flags |= (crct.CH->FB&0xf)<<12;                         /* feedback shift */\r
1122         crct.pack = flags;\r
1123 \r
1124         crct.eg_cnt = ym2612.OPN.eg_cnt;                        /* envelope generator counter */\r
1125         crct.eg_timer = ym2612.OPN.eg_timer;\r
1126 \r
1127         /* precalculate phase modulation incr */\r
1128         crct.phase1 = crct.CH->SLOT[SLOT1].phase;\r
1129         crct.phase2 = crct.CH->SLOT[SLOT2].phase;\r
1130         crct.phase3 = crct.CH->SLOT[SLOT3].phase;\r
1131         crct.phase4 = crct.CH->SLOT[SLOT4].phase;\r
1132 \r
1133         /* current output from EG circuit (without AM from LFO) */\r
1134         crct.vol_out1 = crct.CH->SLOT[SLOT1].tl + ((UINT32)crct.CH->SLOT[SLOT1].volume);\r
1135         crct.vol_out2 = crct.CH->SLOT[SLOT2].tl + ((UINT32)crct.CH->SLOT[SLOT2].volume);\r
1136         crct.vol_out3 = crct.CH->SLOT[SLOT3].tl + ((UINT32)crct.CH->SLOT[SLOT3].volume);\r
1137         crct.vol_out4 = crct.CH->SLOT[SLOT4].tl + ((UINT32)crct.CH->SLOT[SLOT4].volume);\r
1138 \r
1139         crct.op1_out = crct.CH->op1_out;\r
1140         crct.algo = crct.CH->ALGO & 7;\r
1141 \r
1142         if(crct.CH->pms)\r
1143         {\r
1144                 /* add support for 3 slot mode */\r
1145                 UINT32 block_fnum = crct.CH->block_fnum;\r
1146 \r
1147                 UINT32 fnum_lfo   = ((block_fnum & 0x7f0) >> 4) * 32 * 8;\r
1148                 INT32  lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + crct.CH->pms + ((crct.pack>>16)&0xff) ];\r
1149 \r
1150                 if (lfo_fn_table_index_offset)  /* LFO phase modulation active */\r
1151                 {\r
1152                         UINT8  blk;\r
1153                         UINT32 fn;\r
1154                         int kc,fc;\r
1155 \r
1156                         blk = block_fnum >> 11;\r
1157                         block_fnum = block_fnum*2 + lfo_fn_table_index_offset;\r
1158 \r
1159                         fn  = block_fnum & 0xfff;\r
1160 \r
1161                         /* keyscale code */\r
1162                         kc = (blk<<2) | opn_fktable[fn >> 8];\r
1163                         /* phase increment counter */\r
1164                         fc = fn_table[fn]>>(7-blk);\r
1165 \r
1166                         crct.incr1 = ((fc+crct.CH->SLOT[SLOT1].DT[kc])*crct.CH->SLOT[SLOT1].mul) >> 1;\r
1167                         crct.incr2 = ((fc+crct.CH->SLOT[SLOT2].DT[kc])*crct.CH->SLOT[SLOT2].mul) >> 1;\r
1168                         crct.incr3 = ((fc+crct.CH->SLOT[SLOT3].DT[kc])*crct.CH->SLOT[SLOT3].mul) >> 1;\r
1169                         crct.incr4 = ((fc+crct.CH->SLOT[SLOT4].DT[kc])*crct.CH->SLOT[SLOT4].mul) >> 1;\r
1170                 }\r
1171                 else    /* LFO phase modulation  = zero */\r
1172                 {\r
1173                         crct.incr1 = crct.CH->SLOT[SLOT1].Incr;\r
1174                         crct.incr2 = crct.CH->SLOT[SLOT2].Incr;\r
1175                         crct.incr3 = crct.CH->SLOT[SLOT3].Incr;\r
1176                         crct.incr4 = crct.CH->SLOT[SLOT4].Incr;\r
1177                 }\r
1178         }\r
1179         else    /* no LFO phase modulation */\r
1180         {\r
1181                 crct.incr1 = crct.CH->SLOT[SLOT1].Incr;\r
1182                 crct.incr2 = crct.CH->SLOT[SLOT2].Incr;\r
1183                 crct.incr3 = crct.CH->SLOT[SLOT3].Incr;\r
1184                 crct.incr4 = crct.CH->SLOT[SLOT4].Incr;\r
1185         }\r
1186 \r
1187         chan_render_loop(&crct, buffer, length);\r
1188 \r
1189         crct.CH->op1_out = crct.op1_out;\r
1190         crct.CH->mem_value = crct.mem;\r
1191         if (crct.CH->SLOT[SLOT1].state | crct.CH->SLOT[SLOT2].state | crct.CH->SLOT[SLOT3].state | crct.CH->SLOT[SLOT4].state)\r
1192         {\r
1193                 crct.CH->SLOT[SLOT1].phase = crct.phase1;\r
1194                 crct.CH->SLOT[SLOT2].phase = crct.phase2;\r
1195                 crct.CH->SLOT[SLOT3].phase = crct.phase3;\r
1196                 crct.CH->SLOT[SLOT4].phase = crct.phase4;\r
1197         }\r
1198         else\r
1199                 ym2612.slot_mask &= ~(0xf << (c*4));\r
1200 \r
1201         return (crct.algo & 8) >> 3; // had output\r
1202 }\r
1203 \r
1204 /* update phase increment and envelope generator */\r
1205 INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT, int fc, int kc)\r
1206 {\r
1207         int ksr, fdt;\r
1208 \r
1209         /* (frequency) phase increment counter */\r
1210         fdt = fc+SLOT->DT[kc];\r
1211         /* detect overflow */\r
1212 //      if (fdt < 0) fdt += fn_table[0x7ff*2] >> (7-blk-1);\r
1213         if (fdt < 0) fdt += fn_table[0x7ff*2] >> 2;\r
1214         SLOT->Incr = fdt*SLOT->mul >> 1;\r
1215 \r
1216         ksr = kc >> SLOT->KSR;\r
1217         if( SLOT->ksr != ksr )\r
1218         {\r
1219                 int eg_sh, eg_sel;\r
1220                 SLOT->ksr = ksr;\r
1221 \r
1222                 /* calculate envelope generator rates */\r
1223                 if ((SLOT->ar + ksr) < 32+62)\r
1224                 {\r
1225                         eg_sh  = eg_rate_shift [SLOT->ar  + ksr ];\r
1226                         eg_sel = eg_rate_select[SLOT->ar  + ksr ];\r
1227                 }\r
1228                 else\r
1229                 {\r
1230                         eg_sh  = 0;\r
1231                         eg_sel = 17;\r
1232                 }\r
1233 \r
1234                 SLOT->eg_pack_ar = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1235 \r
1236                 eg_sh  = eg_rate_shift [SLOT->d1r + ksr];\r
1237                 eg_sel = eg_rate_select[SLOT->d1r + ksr];\r
1238 \r
1239                 SLOT->eg_pack_d1r = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1240 \r
1241                 eg_sh  = eg_rate_shift [SLOT->d2r + ksr];\r
1242                 eg_sel = eg_rate_select[SLOT->d2r + ksr];\r
1243 \r
1244                 SLOT->eg_pack_d2r = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1245 \r
1246                 eg_sh  = eg_rate_shift [SLOT->rr  + ksr];\r
1247                 eg_sel = eg_rate_select[SLOT->rr  + ksr];\r
1248 \r
1249                 SLOT->eg_pack_rr = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
1250         }\r
1251 }\r
1252 \r
1253 /* update phase increment counters */\r
1254 INLINE void refresh_fc_eg_chan(FM_CH *CH)\r
1255 {\r
1256         if( CH->SLOT[SLOT1].Incr==-1){\r
1257                 int fc = CH->fc;\r
1258                 int kc = CH->kcode;\r
1259                 refresh_fc_eg_slot(&CH->SLOT[SLOT1] , fc , kc );\r
1260                 refresh_fc_eg_slot(&CH->SLOT[SLOT2] , fc , kc );\r
1261                 refresh_fc_eg_slot(&CH->SLOT[SLOT3] , fc , kc );\r
1262                 refresh_fc_eg_slot(&CH->SLOT[SLOT4] , fc , kc );\r
1263         }\r
1264 }\r
1265 \r
1266 INLINE void refresh_fc_eg_chan_sl3(void)\r
1267 {\r
1268         if( ym2612.CH[2].SLOT[SLOT1].Incr==-1)\r
1269         {\r
1270                 refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT1], ym2612.OPN.SL3.fc[1], ym2612.OPN.SL3.kcode[1] );\r
1271                 refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT2], ym2612.OPN.SL3.fc[2], ym2612.OPN.SL3.kcode[2] );\r
1272                 refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT3], ym2612.OPN.SL3.fc[0], ym2612.OPN.SL3.kcode[0] );\r
1273                 refresh_fc_eg_slot(&ym2612.CH[2].SLOT[SLOT4], ym2612.CH[2].fc , ym2612.CH[2].kcode );\r
1274         }\r
1275 }\r
1276 \r
1277 /* initialize time tables */\r
1278 static void init_timetables(const UINT8 *dttable)\r
1279 {\r
1280         int i,d;\r
1281         double rate;\r
1282 \r
1283         /* DeTune table */\r
1284         for (d = 0;d <= 3;d++){\r
1285                 for (i = 0;i <= 31;i++){\r
1286                         rate = ((double)dttable[d*32 + i]) * SIN_LEN  * ym2612.OPN.ST.freqbase  * (1<<FREQ_SH) / ((double)(1<<20));\r
1287                         ym2612.OPN.ST.dt_tab[d][i]   = (INT32) rate;\r
1288                         ym2612.OPN.ST.dt_tab[d+4][i] = -ym2612.OPN.ST.dt_tab[d][i];\r
1289                 }\r
1290         }\r
1291 }\r
1292 \r
1293 \r
1294 static void reset_channels(FM_CH *CH)\r
1295 {\r
1296         int c,s;\r
1297 \r
1298         ym2612.OPN.ST.mode   = 0;       /* normal mode */\r
1299         ym2612.OPN.ST.TA     = 0;\r
1300         ym2612.OPN.ST.TAC    = 0;\r
1301         ym2612.OPN.ST.TB     = 0;\r
1302         ym2612.OPN.ST.TBC    = 0;\r
1303 \r
1304         for( c = 0 ; c < 6 ; c++ )\r
1305         {\r
1306                 CH[c].fc = 0;\r
1307                 for(s = 0 ; s < 4 ; s++ )\r
1308                 {\r
1309                         CH[c].SLOT[s].state= EG_OFF;\r
1310                         CH[c].SLOT[s].volume = MAX_ATT_INDEX;\r
1311                 }\r
1312                 CH[c].mem_value = CH[c].op1_out = 0;\r
1313         }\r
1314         ym2612.slot_mask = 0;\r
1315 }\r
1316 \r
1317 /* initialize generic tables */\r
1318 static void init_tables(void)\r
1319 {\r
1320         signed int i,x,y,p;\r
1321         signed int n;\r
1322         double o,m;\r
1323 \r
1324         for (i=0; i < 256; i++)\r
1325         {\r
1326                 /* non-standard sinus */\r
1327                 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */\r
1328 \r
1329                 /* we never reach zero here due to ((i*2)+1) */\r
1330 \r
1331                 if (m>0.0)\r
1332                         o = 8*log(1.0/m)/log(2);        /* convert to 'decibels' */\r
1333                 else\r
1334                         o = 8*log(-1.0/m)/log(2);       /* convert to 'decibels' */\r
1335 \r
1336                 o = o / (ENV_STEP/4);\r
1337 \r
1338                 n = (int)(2.0*o);\r
1339                 if (n&1)                                                /* round to nearest */\r
1340                         n = (n>>1)+1;\r
1341                 else\r
1342                         n = n>>1;\r
1343 \r
1344                 ym_sin_tab[ i ] = n;\r
1345                 //dprintf("FM.C: sin [%4i]= %4i", i, ym_sin_tab[i]);\r
1346         }\r
1347 \r
1348         //dprintf("FM.C: ENV_QUIET= %08x", ENV_QUIET );\r
1349 \r
1350 \r
1351         for (x=0; x < TL_RES_LEN; x++)\r
1352         {\r
1353                 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);\r
1354                 m = floor(m);\r
1355 \r
1356                 /* we never reach (1<<16) here due to the (x+1) */\r
1357                 /* result fits within 16 bits at maximum */\r
1358 \r
1359                 n = (int)m;             /* 16 bits here */\r
1360                 n >>= 4;                /* 12 bits here */\r
1361                 if (n&1)                /* round to nearest */\r
1362                         n = (n>>1)+1;\r
1363                 else\r
1364                         n = n>>1;\r
1365                                                 /* 11 bits here (rounded) */\r
1366                 n <<= 2;                /* 13 bits here (as in real chip) */\r
1367                 ym_tl_tab2[ x ] = n;\r
1368 \r
1369                 for (i=1; i < 13; i++)\r
1370                 {\r
1371                         ym_tl_tab2[ x + i*TL_RES_LEN ] = n >> i;\r
1372                 }\r
1373         }\r
1374 \r
1375         for (x=0; x < 256; x++)\r
1376         {\r
1377                 int sin = ym_sin_tab[ x ];\r
1378 \r
1379                 for (y=0; y < 2*13*TL_RES_LEN/8; y+=2)\r
1380                 {\r
1381                         p = (y<<2) + sin;\r
1382                         if (p >= 13*TL_RES_LEN)\r
1383                                  ym_tl_tab[(y<<7) | x] = 0;\r
1384                         else ym_tl_tab[(y<<7) | x] = ym_tl_tab2[p];\r
1385                 }\r
1386         }\r
1387 \r
1388 \r
1389         /* build LFO PM modulation table */\r
1390         for(i = 0; i < 8; i++) /* 8 PM depths */\r
1391         {\r
1392                 UINT8 fnum;\r
1393                 for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */\r
1394                 {\r
1395                         UINT8 value;\r
1396                         UINT8 step;\r
1397                         UINT32 offset_depth = i;\r
1398                         UINT32 offset_fnum_bit;\r
1399                         UINT32 bit_tmp;\r
1400 \r
1401                         for (step=0; step<8; step++)\r
1402                         {\r
1403                                 value = 0;\r
1404                                 for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */\r
1405                                 {\r
1406                                         if (fnum & (1<<bit_tmp)) /* only if bit "bit_tmp" is set */\r
1407                                         {\r
1408                                                 offset_fnum_bit = bit_tmp * 8;\r
1409                                                 value += lfo_pm_output[offset_fnum_bit + offset_depth][step];\r
1410                                         }\r
1411                                 }\r
1412                                 lfo_pm_table[(fnum*32*8) + (i*32) + step   + 0] = value;\r
1413                                 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+ 8] = value;\r
1414                                 lfo_pm_table[(fnum*32*8) + (i*32) + step   +16] = -value;\r
1415                                 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+24] = -value;\r
1416                         }\r
1417                 }\r
1418         }\r
1419 }\r
1420 \r
1421 \r
1422 /* CSM Key Controll */\r
1423 #if 0\r
1424 INLINE void CSMKeyControll(FM_CH *CH)\r
1425 {\r
1426         /* this is wrong, atm */\r
1427 \r
1428         /* all key on */\r
1429         FM_KEYON(CH,SLOT1);\r
1430         FM_KEYON(CH,SLOT2);\r
1431         FM_KEYON(CH,SLOT3);\r
1432         FM_KEYON(CH,SLOT4);\r
1433 }\r
1434 #endif\r
1435 \r
1436 \r
1437 /* prescaler set (and make time tables) */\r
1438 static void OPNSetPres(int pres)\r
1439 {\r
1440         int i;\r
1441 \r
1442         /* frequency base */\r
1443         ym2612.OPN.ST.freqbase = (ym2612.OPN.ST.rate) ? ((double)ym2612.OPN.ST.clock / ym2612.OPN.ST.rate) / pres : 0;\r
1444 \r
1445         ym2612.OPN.eg_timer_add  = (1<<EG_SH) * ym2612.OPN.ST.freqbase;\r
1446 \r
1447         /* make time tables */\r
1448         init_timetables( dt_tab );\r
1449 \r
1450         /* there are 2048 FNUMs that can be generated using FNUM/BLK registers\r
1451         but LFO works with one more bit of a precision so we really need 4096 elements */\r
1452         /* calculate fnumber -> increment counter table */\r
1453         for(i = 0; i < 4096; i++)\r
1454         {\r
1455                 /* freq table for octave 7 */\r
1456                 /* OPN phase increment counter = 20bit */\r
1457                 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
1458         }\r
1459 \r
1460         /* LFO freq. table */\r
1461         for(i = 0; i < 8; i++)\r
1462         {\r
1463                 /* Amplitude modulation: 64 output levels (triangle waveform); 1 level lasts for one of "lfo_samples_per_step" samples */\r
1464                 /* Phase modulation: one entry from lfo_pm_output lasts for one of 4 * "lfo_samples_per_step" samples  */\r
1465                 ym2612.OPN.lfo_freq[i] = (1.0 / lfo_samples_per_step[i]) * (1<<LFO_SH) * ym2612.OPN.ST.freqbase;\r
1466         }\r
1467 }\r
1468 \r
1469 \r
1470 /* write a OPN register (0x30-0xff) */\r
1471 static int OPNWriteReg(int r, int v)\r
1472 {\r
1473         int ret = 1;\r
1474         FM_CH *CH;\r
1475         FM_SLOT *SLOT;\r
1476 \r
1477         UINT8 c = OPN_CHAN(r);\r
1478 \r
1479         if (c == 3) return 0; /* 0xX3,0xX7,0xXB,0xXF */\r
1480 \r
1481         if (r >= 0x100) c+=3;\r
1482 \r
1483         CH = &ym2612.CH[c];\r
1484 \r
1485         SLOT = &(CH->SLOT[OPN_SLOT(r)]);\r
1486 \r
1487         switch( r & 0xf0 ) {\r
1488         case 0x30:      /* DET , MUL */\r
1489                 set_det_mul(CH,SLOT,v);\r
1490                 break;\r
1491 \r
1492         case 0x40:      /* TL */\r
1493                 set_tl(SLOT,v);\r
1494                 break;\r
1495 \r
1496         case 0x50:      /* KS, AR */\r
1497                 set_ar_ksr(CH,SLOT,v);\r
1498                 break;\r
1499 \r
1500         case 0x60:      /* bit7 = AM ENABLE, DR | depends on ksr */\r
1501                 set_dr(SLOT,v);\r
1502                 if(v&0x80) CH->AMmasks |=   1<<OPN_SLOT(r);\r
1503                 else       CH->AMmasks &= ~(1<<OPN_SLOT(r));\r
1504                 break;\r
1505 \r
1506         case 0x70:      /*     SR | depends on ksr */\r
1507                 set_sr(SLOT,v);\r
1508                 break;\r
1509 \r
1510         case 0x80:      /* SL, RR | depends on ksr */\r
1511                 set_sl_rr(SLOT,v);\r
1512                 break;\r
1513 \r
1514         case 0x90:      /* SSG-EG */\r
1515                 // removed.\r
1516                 ret = 0;\r
1517                 break;\r
1518 \r
1519         case 0xa0:\r
1520                 switch( OPN_SLOT(r) ){\r
1521                 case 0:         /* 0xa0-0xa2 : FNUM1 | depends on fn_h (below) */\r
1522                         {\r
1523                                 UINT32 fn = (((UINT32)( (CH->fn_h)&7))<<8) + v;\r
1524                                 UINT8 blk = CH->fn_h>>3;\r
1525                                 /* keyscale code */\r
1526                                 CH->kcode = (blk<<2) | opn_fktable[fn >> 7];\r
1527                                 /* phase increment counter */\r
1528                                 CH->fc = fn_table[fn*2]>>(7-blk);\r
1529 \r
1530                                 /* store fnum in clear form for LFO PM calculations */\r
1531                                 CH->block_fnum = (blk<<11) | fn;\r
1532 \r
1533                                 CH->SLOT[SLOT1].Incr=-1;\r
1534                         }\r
1535                         break;\r
1536                 case 1:         /* 0xa4-0xa6 : FNUM2,BLK */\r
1537                         CH->fn_h = v&0x3f;\r
1538                         ret = 0;\r
1539                         break;\r
1540                 case 2:         /* 0xa8-0xaa : 3CH FNUM1 */\r
1541                         if(r < 0x100)\r
1542                         {\r
1543                                 UINT32 fn = (((UINT32)(ym2612.OPN.SL3.fn_h&7))<<8) + v;\r
1544                                 UINT8 blk = ym2612.OPN.SL3.fn_h>>3;\r
1545                                 /* keyscale code */\r
1546                                 ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];\r
1547                                 /* phase increment counter */\r
1548                                 ym2612.OPN.SL3.fc[c] = fn_table[fn*2]>>(7-blk);\r
1549                                 ym2612.OPN.SL3.block_fnum[c] = (blk<<11) | fn;\r
1550                                 ym2612.CH[2].SLOT[SLOT1].Incr=-1;\r
1551                         }\r
1552                         break;\r
1553                 case 3:         /* 0xac-0xae : 3CH FNUM2,BLK */\r
1554                         if(r < 0x100)\r
1555                                 ym2612.OPN.SL3.fn_h = v&0x3f;\r
1556                         ret = 0;\r
1557                         break;\r
1558                 default:\r
1559                         ret = 0;\r
1560                         break;\r
1561                 }\r
1562                 break;\r
1563 \r
1564         case 0xb0:\r
1565                 switch( OPN_SLOT(r) ){\r
1566                 case 0:         /* 0xb0-0xb2 : FB,ALGO */\r
1567                         {\r
1568                                 int feedback = (v>>3)&7;\r
1569                                 CH->ALGO = v&7;\r
1570                                 CH->FB   = feedback ? feedback+6 : 0;\r
1571                         }\r
1572                         break;\r
1573                 case 1:         /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */\r
1574                         {\r
1575                                 int panshift = c<<1;\r
1576 \r
1577                                 /* b0-2 PMS */\r
1578                                 CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */\r
1579 \r
1580                                 /* b4-5 AMS */\r
1581                                 CH->ams = lfo_ams_depth_shift[(v>>4) & 3];\r
1582 \r
1583                                 /* PAN :  b7 = L, b6 = R */\r
1584                                 ym2612.OPN.pan &= ~(3<<panshift);\r
1585                                 ym2612.OPN.pan |= ((v & 0xc0) >> 6) << panshift; // ..LRLR\r
1586                         }\r
1587                         break;\r
1588                 default:\r
1589                         ret = 0;\r
1590                         break;\r
1591                 }\r
1592                 break;\r
1593         default:\r
1594                 ret = 0;\r
1595                 break;\r
1596         }\r
1597 \r
1598         return ret;\r
1599 }\r
1600 \r
1601 \r
1602 /*******************************************************************************/\r
1603 /*      YM2612 local section                                                   */\r
1604 /*******************************************************************************/\r
1605 \r
1606 /* Generate samples for YM2612 */\r
1607 int YM2612UpdateOne_(int *buffer, int length, int stereo, int is_buf_empty)\r
1608 {\r
1609         int pan;\r
1610         int active_chs = 0;\r
1611 \r
1612         // if !is_buf_empty, it means it has valid samples to mix with, else it may contain trash\r
1613         if (is_buf_empty) memset32(buffer, 0, length<<stereo);\r
1614 \r
1615 /*\r
1616         {\r
1617                 int c, s;\r
1618                 ppp();\r
1619                 for (c = 0; c < 6; c++) {\r
1620                         int slr = 0, slm;\r
1621                         printf("%i: ", c);\r
1622                         for (s = 0; s < 4; s++) {\r
1623                                 if (ym2612.CH[c].SLOT[s].state != EG_OFF) slr = 1;\r
1624                                 printf(" %i", ym2612.CH[c].SLOT[s].state != EG_OFF);\r
1625                         }\r
1626                         slm = (ym2612.slot_mask&(0xf<<(c*4))) ? 1 : 0;\r
1627                         printf(" | %i", slm);\r
1628                         printf(" | %i\n", ym2612.CH[c].SLOT[SLOT1].Incr==-1);\r
1629                         if (slr != slm) exit(1);\r
1630                 }\r
1631         }\r
1632 */\r
1633         /* refresh PG and EG */\r
1634         refresh_fc_eg_chan( &ym2612.CH[0] );\r
1635         refresh_fc_eg_chan( &ym2612.CH[1] );\r
1636         if( (ym2612.OPN.ST.mode & 0xc0) )\r
1637                 /* 3SLOT MODE */\r
1638                 refresh_fc_eg_chan_sl3();\r
1639         else\r
1640                 refresh_fc_eg_chan( &ym2612.CH[2] );\r
1641         refresh_fc_eg_chan( &ym2612.CH[3] );\r
1642         refresh_fc_eg_chan( &ym2612.CH[4] );\r
1643         refresh_fc_eg_chan( &ym2612.CH[5] );\r
1644 \r
1645         pan = ym2612.OPN.pan;\r
1646         if (stereo) stereo = 1;\r
1647 \r
1648         /* mix to 32bit dest */\r
1649         // flags: stereo, ?, disabled, ?, pan_r, pan_l\r
1650         chan_render_prep();\r
1651         if (ym2612.slot_mask & 0x00000f) active_chs |= chan_render(buffer, length, 0, stereo|((pan&0x003)<<4)) << 0;\r
1652         if (ym2612.slot_mask & 0x0000f0) active_chs |= chan_render(buffer, length, 1, stereo|((pan&0x00c)<<2)) << 1;\r
1653         if (ym2612.slot_mask & 0x000f00) active_chs |= chan_render(buffer, length, 2, stereo|((pan&0x030)   )) << 2;\r
1654         if (ym2612.slot_mask & 0x00f000) active_chs |= chan_render(buffer, length, 3, stereo|((pan&0x0c0)>>2)) << 3;\r
1655         if (ym2612.slot_mask & 0x0f0000) active_chs |= chan_render(buffer, length, 4, stereo|((pan&0x300)>>4)) << 4;\r
1656         if (ym2612.slot_mask & 0xf00000) active_chs |= chan_render(buffer, length, 5, stereo|((pan&0xc00)>>6)|(ym2612.dacen<<2)) << 5;\r
1657         chan_render_finish();\r
1658 \r
1659         return active_chs; // 1 if buffer updated\r
1660 }\r
1661 \r
1662 \r
1663 /* initialize YM2612 emulator */\r
1664 void YM2612Init_(int clock, int rate)\r
1665 {\r
1666         memset(&ym2612, 0, sizeof(ym2612));\r
1667         init_tables();\r
1668 \r
1669         ym2612.OPN.ST.clock = clock;\r
1670         ym2612.OPN.ST.rate = rate;\r
1671 \r
1672         OPNSetPres( 6*24 );\r
1673 \r
1674         /* Extend handler */\r
1675         YM2612ResetChip_();\r
1676 }\r
1677 \r
1678 \r
1679 /* reset */\r
1680 void YM2612ResetChip_(void)\r
1681 {\r
1682         int i;\r
1683 \r
1684         memset(ym2612.REGS, 0, sizeof(ym2612.REGS));\r
1685 \r
1686         set_timers( 0x30 ); /* mode 0 , timer reset */\r
1687         ym2612.REGS[0x27] = 0x30;\r
1688 \r
1689         ym2612.OPN.eg_timer = 0;\r
1690         ym2612.OPN.eg_cnt   = 0;\r
1691         ym2612.OPN.ST.status = 0;\r
1692 \r
1693         reset_channels( &ym2612.CH[0] );\r
1694         for(i = 0xb6 ; i >= 0xb4 ; i-- )\r
1695         {\r
1696                 OPNWriteReg(i      ,0xc0);\r
1697                 OPNWriteReg(i|0x100,0xc0);\r
1698                 ym2612.REGS[i      ] = 0xc0;\r
1699                 ym2612.REGS[i|0x100] = 0xc0;\r
1700         }\r
1701         for(i = 0xb2 ; i >= 0x30 ; i-- )\r
1702         {\r
1703                 OPNWriteReg(i      ,0);\r
1704                 OPNWriteReg(i|0x100,0);\r
1705         }\r
1706         for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0);\r
1707         /* DAC mode clear */\r
1708         ym2612.dacen = 0;\r
1709         ym2612.addr_A1 = 0;\r
1710 }\r
1711 \r
1712 \r
1713 /* YM2612 write */\r
1714 /* a = address */\r
1715 /* v = value   */\r
1716 /* returns 1 if sample affecting state changed */\r
1717 int YM2612Write_(unsigned int a, unsigned int v)\r
1718 {\r
1719         int addr, ret=1;\r
1720 \r
1721         v &= 0xff;      /* adjust to 8 bit bus */\r
1722 \r
1723         switch( a&3){\r
1724         case 0: /* address port 0 */\r
1725                 ym2612.OPN.ST.address = v;\r
1726                 ym2612.addr_A1 = 0;\r
1727                 ret=0;\r
1728                 break;\r
1729 \r
1730         case 1: /* data port 0    */\r
1731                 if (ym2612.addr_A1 != 0) {\r
1732                         ret=0;\r
1733                         break;  /* verified on real YM2608 */\r
1734                 }\r
1735 \r
1736                 addr = ym2612.OPN.ST.address;\r
1737 \r
1738                 switch( addr & 0xf0 )\r
1739                 {\r
1740                 case 0x20:      /* 0x20-0x2f Mode */\r
1741                         switch( addr )\r
1742                         {\r
1743                         case 0x22:      /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */\r
1744                                 if (v&0x08) /* LFO enabled ? */\r
1745                                 {\r
1746                                         ym2612.OPN.lfo_inc = ym2612.OPN.lfo_freq[v&7];\r
1747                                 }\r
1748                                 else\r
1749                                 {\r
1750                                         ym2612.OPN.lfo_inc = 0;\r
1751                                 }\r
1752                                 break;\r
1753 #if 0 // handled elsewhere\r
1754                         case 0x24: { // timer A High 8\r
1755                                         int TAnew = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2);\r
1756                                         if(ym2612.OPN.ST.TA != TAnew) {\r
1757                                                 // we should reset ticker only if new value is written. Outrun requires this.\r
1758                                                 ym2612.OPN.ST.TA = TAnew;\r
1759                                                 ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
1760                                                 ym2612.OPN.ST.TAT = 0;\r
1761                                         }\r
1762                                 }\r
1763                                 ret=0;\r
1764                                 break;\r
1765                         case 0x25: { // timer A Low 2\r
1766                                         int TAnew = (ym2612.OPN.ST.TA & 0x3fc)|(v&3);\r
1767                                         if(ym2612.OPN.ST.TA != TAnew) {\r
1768                                                 ym2612.OPN.ST.TA = TAnew;\r
1769                                                 ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
1770                                                 ym2612.OPN.ST.TAT = 0;\r
1771                                         }\r
1772                                 }\r
1773                                 ret=0;\r
1774                                 break;\r
1775                         case 0x26: // timer B\r
1776                                 if(ym2612.OPN.ST.TB != v) {\r
1777                                         ym2612.OPN.ST.TB = v;\r
1778                                         ym2612.OPN.ST.TBC  = (256-v)<<4;\r
1779                                         ym2612.OPN.ST.TBC *= 18;\r
1780                                         ym2612.OPN.ST.TBT  = 0;\r
1781                                 }\r
1782                                 ret=0;\r
1783                                 break;\r
1784 #endif\r
1785                         case 0x27:      /* mode, timer control */\r
1786                                 set_timers( v );\r
1787                                 ret=0;\r
1788                                 break;\r
1789                         case 0x28:      /* key on / off */\r
1790                                 {\r
1791                                         UINT8 c;\r
1792 \r
1793                                         c = v & 0x03;\r
1794                                         if( c == 3 ) { ret=0; break; }\r
1795                                         if( v&0x04 ) c+=3;\r
1796                                         if(v&0x10) FM_KEYON(c,SLOT1); else FM_KEYOFF(c,SLOT1);\r
1797                                         if(v&0x20) FM_KEYON(c,SLOT2); else FM_KEYOFF(c,SLOT2);\r
1798                                         if(v&0x40) FM_KEYON(c,SLOT3); else FM_KEYOFF(c,SLOT3);\r
1799                                         if(v&0x80) FM_KEYON(c,SLOT4); else FM_KEYOFF(c,SLOT4);\r
1800                                         break;\r
1801                                 }\r
1802                         case 0x2a:      /* DAC data (YM2612) */\r
1803                                 ym2612.dacout = ((int)v - 0x80) << 6;   /* level unknown (notaz: 8 seems to be too much) */\r
1804                                 ret=0;\r
1805                                 break;\r
1806                         case 0x2b:      /* DAC Sel  (YM2612) */\r
1807                                 /* b7 = dac enable */\r
1808                                 ym2612.dacen = v & 0x80;\r
1809                                 ret=0;\r
1810                                 break;\r
1811                         default:\r
1812                                 break;\r
1813                         }\r
1814                         break;\r
1815                 default:        /* 0x30-0xff OPN section */\r
1816                         /* write register */\r
1817                         ret = OPNWriteReg(addr,v);\r
1818                 }\r
1819                 break;\r
1820 \r
1821         case 2: /* address port 1 */\r
1822                 ym2612.OPN.ST.address = v;\r
1823                 ym2612.addr_A1 = 1;\r
1824                 ret=0;\r
1825                 break;\r
1826 \r
1827         case 3: /* data port 1    */\r
1828                 if (ym2612.addr_A1 != 1) {\r
1829                         ret=0;\r
1830                         break;  /* verified on real YM2608 */\r
1831                 }\r
1832 \r
1833                 addr = ym2612.OPN.ST.address | 0x100;\r
1834 \r
1835                 ret = OPNWriteReg(addr, v);\r
1836                 break;\r
1837         }\r
1838 \r
1839         return ret;\r
1840 }\r
1841 \r
1842 #if 0\r
1843 UINT8 YM2612Read_(void)\r
1844 {\r
1845         return ym2612.OPN.ST.status;\r
1846 }\r
1847 \r
1848 int YM2612PicoTick_(int n)\r
1849 {\r
1850         int ret = 0;\r
1851 \r
1852         // timer A\r
1853         if(ym2612.OPN.ST.mode & 0x01 && (ym2612.OPN.ST.TAT+=64*n) >= ym2612.OPN.ST.TAC) {\r
1854                 ym2612.OPN.ST.TAT -= ym2612.OPN.ST.TAC;\r
1855                 if(ym2612.OPN.ST.mode & 0x04) ym2612.OPN.ST.status |= 1;\r
1856                 // CSM mode total level latch and auto key on\r
1857                 if(ym2612.OPN.ST.mode & 0x80) {\r
1858                         CSMKeyControll( &(ym2612.CH[2]) ); // Vectorman2, etc.\r
1859                         ret = 1;\r
1860                 }\r
1861         }\r
1862 \r
1863         // timer B\r
1864         if(ym2612.OPN.ST.mode & 0x02 && (ym2612.OPN.ST.TBT+=64*n) >= ym2612.OPN.ST.TBC) {\r
1865                 ym2612.OPN.ST.TBT -= ym2612.OPN.ST.TBC;\r
1866                 if(ym2612.OPN.ST.mode & 0x08) ym2612.OPN.ST.status |= 2;\r
1867         }\r
1868 \r
1869         return ret;\r
1870 }\r
1871 #endif\r
1872 \r
1873 void YM2612PicoStateLoad_(void)\r
1874 {\r
1875         reset_channels( &ym2612.CH[0] );\r
1876         ym2612.slot_mask = 0xffffff;\r
1877 }\r
1878 \r
1879 /* rather stupid design because I wanted to fit in unused register "space" */\r
1880 typedef struct\r
1881 {\r
1882         UINT32  state_phase;\r
1883         INT16   volume;\r
1884 } ym_save_addon_slot;\r
1885 \r
1886 typedef struct\r
1887 {\r
1888         UINT32  magic;\r
1889         UINT8   address;\r
1890         UINT8   status;\r
1891         UINT8   addr_A1;\r
1892         UINT8   unused;\r
1893         int     TAT;\r
1894         int     TBT;\r
1895         UINT32  eg_cnt;         // 10\r
1896         UINT32  eg_timer;\r
1897         UINT32  lfo_cnt;\r
1898         UINT16  lfo_ampm;\r
1899         UINT16  unused2;\r
1900         UINT32  keyon_field;    // 20\r
1901         UINT32  kcode_fc_sl3_3;\r
1902         UINT32  reserved[2];\r
1903 } ym_save_addon;\r
1904 \r
1905 typedef struct\r
1906 {\r
1907         UINT16  block_fnum[6];\r
1908         UINT16  block_fnum_sl3[3];\r
1909         UINT16  reserved[7];\r
1910 } ym_save_addon2;\r
1911 \r
1912 \r
1913 void YM2612PicoStateSave2(int tat, int tbt)\r
1914 {\r
1915         ym_save_addon_slot ss;\r
1916         ym_save_addon2 sa2;\r
1917         ym_save_addon sa;\r
1918         unsigned char *ptr;\r
1919         int c, s;\r
1920 \r
1921         memset(&sa, 0, sizeof(sa));\r
1922         memset(&sa2, 0, sizeof(sa2));\r
1923 \r
1924         // chans 1,2,3\r
1925         ptr = &ym2612.REGS[0x0b8];\r
1926         for (c = 0; c < 3; c++)\r
1927         {\r
1928                 for (s = 0; s < 4; s++) {\r
1929                         ss.state_phase = (ym2612.CH[c].SLOT[s].state << 29) | (ym2612.CH[c].SLOT[s].phase >> 3);\r
1930                         ss.volume = ym2612.CH[c].SLOT[s].volume;\r
1931                         if (ym2612.CH[c].SLOT[s].key)\r
1932                                 sa.keyon_field |= 1 << (c*4 + s);\r
1933                         memcpy(ptr, &ss, 6);\r
1934                         ptr += 6;\r
1935                 }\r
1936                 sa2.block_fnum[c] = ym2612.CH[c].block_fnum;\r
1937         }\r
1938         // chans 4,5,6\r
1939         ptr = &ym2612.REGS[0x1b8];\r
1940         for (; c < 6; c++)\r
1941         {\r
1942                 for (s = 0; s < 4; s++) {\r
1943                         ss.state_phase = (ym2612.CH[c].SLOT[s].state << 29) | (ym2612.CH[c].SLOT[s].phase >> 3);\r
1944                         ss.volume = ym2612.CH[c].SLOT[s].volume;\r
1945                         if (ym2612.CH[c].SLOT[s].key)\r
1946                                 sa.keyon_field |= 1 << (c*4 + s);\r
1947                         memcpy(ptr, &ss, 6);\r
1948                         ptr += 6;\r
1949                 }\r
1950                 sa2.block_fnum[c] = ym2612.CH[c].block_fnum;\r
1951         }\r
1952         for (c = 0; c < 3; c++)\r
1953         {\r
1954                 sa2.block_fnum_sl3[c] = ym2612.OPN.SL3.block_fnum[c];\r
1955         }\r
1956 \r
1957         memcpy(&ym2612.REGS[0], &sa2, sizeof(sa2)); // 0x20 max\r
1958 \r
1959         // other things\r
1960         ptr = &ym2612.REGS[0x100];\r
1961         sa.magic = 0x41534d59; // 'YMSA'\r
1962         sa.address = ym2612.OPN.ST.address;\r
1963         sa.status  = ym2612.OPN.ST.status;\r
1964         sa.addr_A1 = ym2612.addr_A1;\r
1965         sa.TAT     = tat;\r
1966         sa.TBT     = tbt;\r
1967         sa.eg_cnt  = ym2612.OPN.eg_cnt;\r
1968         sa.eg_timer = ym2612.OPN.eg_timer;\r
1969         sa.lfo_cnt  = ym2612.OPN.lfo_cnt;\r
1970         sa.lfo_ampm = g_lfo_ampm;\r
1971         memcpy(ptr, &sa, sizeof(sa)); // 0x30 max\r
1972 }\r
1973 \r
1974 int YM2612PicoStateLoad2(int *tat, int *tbt)\r
1975 {\r
1976         ym_save_addon_slot ss;\r
1977         ym_save_addon2 sa2;\r
1978         ym_save_addon sa;\r
1979         unsigned char *ptr;\r
1980         UINT32 fn;\r
1981         UINT8 blk;\r
1982         int c, s;\r
1983 \r
1984         ptr = &ym2612.REGS[0x100];\r
1985         memcpy(&sa, ptr, sizeof(sa)); // 0x30 max\r
1986         if (sa.magic != 0x41534d59) return -1;\r
1987 \r
1988         ptr = &ym2612.REGS[0];\r
1989         memcpy(&sa2, ptr, sizeof(sa2));\r
1990 \r
1991         ym2612.OPN.ST.address = sa.address;\r
1992         ym2612.OPN.ST.status = sa.status;\r
1993         ym2612.addr_A1 = sa.addr_A1;\r
1994         ym2612.OPN.eg_cnt = sa.eg_cnt;\r
1995         ym2612.OPN.eg_timer = sa.eg_timer;\r
1996         ym2612.OPN.lfo_cnt = sa.lfo_cnt;\r
1997         g_lfo_ampm = sa.lfo_ampm;\r
1998         if (tat != NULL) *tat = sa.TAT;\r
1999         if (tbt != NULL) *tbt = sa.TBT;\r
2000 \r
2001         // chans 1,2,3\r
2002         ptr = &ym2612.REGS[0x0b8];\r
2003         for (c = 0; c < 3; c++)\r
2004         {\r
2005                 for (s = 0; s < 4; s++) {\r
2006                         memcpy(&ss, ptr, 6);\r
2007                         ym2612.CH[c].SLOT[s].state = ss.state_phase >> 29;\r
2008                         ym2612.CH[c].SLOT[s].phase = ss.state_phase << 3;\r
2009                         ym2612.CH[c].SLOT[s].volume = ss.volume;\r
2010                         ym2612.CH[c].SLOT[s].key = (sa.keyon_field & (1 << (c*4 + s))) ? 1 : 0;\r
2011                         ym2612.CH[c].SLOT[s].ksr = (UINT8)-1;\r
2012                         ptr += 6;\r
2013                 }\r
2014                 ym2612.CH[c].SLOT[SLOT1].Incr=-1;\r
2015                 ym2612.CH[c].block_fnum = sa2.block_fnum[c];\r
2016                 fn = ym2612.CH[c].block_fnum & 0x7ff;\r
2017                 blk = ym2612.CH[c].block_fnum >> 11;\r
2018                 ym2612.CH[c].kcode= (blk<<2) | opn_fktable[fn >> 7];\r
2019                 ym2612.CH[c].fc = fn_table[fn*2]>>(7-blk);\r
2020         }\r
2021         // chans 4,5,6\r
2022         ptr = &ym2612.REGS[0x1b8];\r
2023         for (; c < 6; c++)\r
2024         {\r
2025                 for (s = 0; s < 4; s++) {\r
2026                         memcpy(&ss, ptr, 6);\r
2027                         ym2612.CH[c].SLOT[s].state = ss.state_phase >> 29;\r
2028                         ym2612.CH[c].SLOT[s].phase = ss.state_phase << 3;\r
2029                         ym2612.CH[c].SLOT[s].volume = ss.volume;\r
2030                         ym2612.CH[c].SLOT[s].key = (sa.keyon_field & (1 << (c*4 + s))) ? 1 : 0;\r
2031                         ym2612.CH[c].SLOT[s].ksr = (UINT8)-1;\r
2032                         ptr += 6;\r
2033                 }\r
2034                 ym2612.CH[c].SLOT[SLOT1].Incr=-1;\r
2035                 ym2612.CH[c].block_fnum = sa2.block_fnum[c];\r
2036                 fn = ym2612.CH[c].block_fnum & 0x7ff;\r
2037                 blk = ym2612.CH[c].block_fnum >> 11;\r
2038                 ym2612.CH[c].kcode= (blk<<2) | opn_fktable[fn >> 7];\r
2039                 ym2612.CH[c].fc = fn_table[fn*2]>>(7-blk);\r
2040         }\r
2041         for (c = 0; c < 3; c++)\r
2042         {\r
2043                 ym2612.OPN.SL3.block_fnum[c] = sa2.block_fnum_sl3[c];\r
2044                 fn = ym2612.OPN.SL3.block_fnum[c] & 0x7ff;\r
2045                 blk = ym2612.OPN.SL3.block_fnum[c] >> 11;\r
2046                 ym2612.OPN.SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];\r
2047                 ym2612.OPN.SL3.fc[c] = fn_table[fn*2]>>(7-blk);\r
2048         }\r
2049 \r
2050         return 0;\r
2051 }\r
2052 \r
2053 void *YM2612GetRegs(void)\r
2054 {\r
2055         return ym2612.REGS;\r
2056 }\r
2057 \r