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