1 /*
2 **
3 ** File: fm2612.c -- software implementation of Yamaha YM2612 FM sound generator
4 ** Split from fm.c to keep 2612 fixes from infecting other OPN chips
5 **
6 ** Copyright Jarek Burczynski (bujar at mame dot net)
7 ** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development
8 **
9 ** Version 1.5.1 (Genesis Plus GX ym2612.c rev. 368)
10 **
11 */
12
13 /*
14 ** History:
15 **
16 ** 2006~2012 Eke-Eke (Genesis Plus GX):
17 ** Huge thanks to Nemesis, lot of those fixes came from his tests on Sega Genesis hardware
18 ** More informations at http://gendev.spritesmind.net/forum/viewtopic.php?t=386
19 **
20 ** TODO:
21 **
22 ** - core documentation
23 ** - BUSY flag support
24 **
25 ** CHANGELOG:
26 **
27 ** - fixed LFO implementation:
28 ** .added support for CH3 special mode: fixes various sound effects (birds in Warlock, bug sound in Aladdin...)
29 ** .inverted LFO AM waveform: fixes Spider-Man & Venom : Separation Anxiety (intro), California Games (surfing event)
30 ** .improved LFO timing accuracy: now updated AFTER sample output, like EG/PG updates, and without any precision loss anymore.
31 ** - improved internal timers emulation
32 ** - adjusted lowest EG rates increment values
33 ** - fixed Attack Rate not being updated in some specific cases (Batman & Robin intro)
34 ** - fixed EG behavior when Attack Rate is maximal
35 ** - fixed EG behavior when SL=0 (Mega Turrican tracks 03,09...) or/and Key ON occurs at minimal attenuation
36 ** - implemented EG output immediate changes on register writes
37 ** - fixed YM2612 initial values (after the reset): fixes missing intro in B.O.B
38 ** - implemented Detune overflow (Ariel, Comix Zone, Shaq Fu, Spiderman & many other games using GEMS sound engine)
39 ** - implemented accurate CSM mode emulation
40 ** - implemented accurate SSG-EG emulation (Asterix, Beavis&Butthead, Bubba'n Stix & many other games)
41 ** - implemented accurate address/data ports behavior
42 **
43 ** 06-23-2007 Zsolt Vasvari:
44 ** - changed the timing not to require the use of floating point calculations
45 **
46 ** 03-08-2003 Jarek Burczynski:
47 ** - fixed YM2608 initial values (after the reset)
48 ** - fixed flag and irqmask handling (YM2608)
49 ** - fixed BUFRDY flag handling (YM2608)
50 **
51 ** 14-06-2003 Jarek Burczynski:
52 ** - implemented all of the YM2608 status register flags
53 ** - implemented support for external memory read/write via YM2608
54 ** - implemented support for deltat memory limit register in YM2608 emulation
55 **
56 ** 22-05-2003 Jarek Burczynski:
57 ** - fixed LFO PM calculations (copy&paste bugfix)
58 **
59 ** 08-05-2003 Jarek Burczynski:
60 ** - fixed SSG support
61 **
62 ** 22-04-2003 Jarek Burczynski:
63 ** - implemented 100% correct LFO generator (verified on real YM2610 and YM2608)
64 **
65 ** 15-04-2003 Jarek Burczynski:
66 ** - added support for YM2608's register 0x110 - status mask
67 **
68 ** 01-12-2002 Jarek Burczynski:
69 ** - fixed register addressing in YM2608, YM2610, YM2610B chips. (verified on real YM2608)
70 ** The addressing patch used for early Neo-Geo games can be removed now.
71 **
72 ** 26-11-2002 Jarek Burczynski, Nicola Salmoria:
73 ** - recreated YM2608 ADPCM ROM using data from real YM2608's output which leads to:
74 ** - added emulation of YM2608 drums.
75 ** - output of YM2608 is two times lower now - same as YM2610 (verified on real YM2608)
76 **
77 ** 16-08-2002 Jarek Burczynski:
78 ** - binary exact Envelope Generator (verified on real YM2203);
79 ** identical to YM2151
80 ** - corrected 'off by one' error in feedback calculations (when feedback is off)
81 ** - corrected connection (algorithm) calculation (verified on real YM2203 and YM2610)
82 **
83 ** 18-12-2001 Jarek Burczynski:
84 ** - added SSG-EG support (verified on real YM2203)
85 **
86 ** 12-08-2001 Jarek Burczynski:
87 ** - corrected sin_tab and tl_tab data (verified on real chip)
88 ** - corrected feedback calculations (verified on real chip)
89 ** - corrected phase generator calculations (verified on real chip)
90 ** - corrected envelope generator calculations (verified on real chip)
91 ** - corrected FM volume level (YM2610 and YM2610B).
92 ** - changed YMxxxUpdateOne() functions (YM2203, YM2608, YM2610, YM2610B, YM2612) :
93 ** this was needed to calculate YM2610 FM channels output correctly.
94 ** (Each FM channel is calculated as in other chips, but the output of the channel
95 ** gets shifted right by one *before* sending to accumulator. That was impossible to do
96 ** with previous implementation).
97 **
98 ** 23-07-2001 Jarek Burczynski, Nicola Salmoria:
99 ** - corrected YM2610 ADPCM type A algorithm and tables (verified on real chip)
100 **
101 ** 11-06-2001 Jarek Burczynski:
102 ** - corrected end of sample bug in ADPCMA_calc_cha().
103 ** Real YM2610 checks for equality between current and end addresses (only 20 LSB bits).
104 **
105 ** 08-12-98 hiro-shi:
106 ** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA
107 ** move ROM limit check.(CALC_CH? -> 2610Write1/2)
108 ** test program (ADPCMB_TEST)
109 ** move ADPCM A/B end check.
110 ** ADPCMB repeat flag(no check)
111 ** change ADPCM volume rate (8->16) (32->48).
112 **
113 ** 09-12-98 hiro-shi:
114 ** change ADPCM volume. (8->16, 48->64)
115 ** replace ym2610 ch0/3 (YM-2610B)
116 ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
117 ** add ADPCM_SHIFT_MASK
118 ** change ADPCMA_DECODE_MIN/MAX.
119 */
120
121
122
123
124 /************************************************************************/
125 /* comment of hiro-shi(Hiromitsu Shioya) */
126 /* YM2610(B) = OPN-B */
127 /* YM2610 : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
128 /* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
129 /************************************************************************/
130
131 //#include "emu.h"
132 #include <stdlib.h>
133 #include <memory.h>
134 #include <math.h>
135 #include "mamedef.h"
136 #include "fm.h"
137
138 #define NULL ((void *)0)
139
140 /* shared function building option */
141 #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B||BUILD_YM2612||BUILD_YM3438)
142 #define BUILD_OPN_PRESCALER (BUILD_YM2203||BUILD_YM2608)
143
144
145 /* globals */
146 #define TYPE_SSG 0x01 /* SSG support */
147 #define TYPE_LFOPAN 0x02 /* OPN type LFO and PAN */
148 #define TYPE_6CH 0x04 /* FM 6CH / 3CH */
149 #define TYPE_DAC 0x08 /* YM2612's DAC device */
150 #define TYPE_ADPCM 0x10 /* two ADPCM units */
151 #define TYPE_2610 0x20 /* bogus flag to differentiate 2608 from 2610 */
152
153
154 #define TYPE_YM2203 (TYPE_SSG)
155 #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
156 #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM |TYPE_2610)
157 #define TYPE_YM2612 (TYPE_DAC |TYPE_LFOPAN |TYPE_6CH)
158
159
160 /* globals */
161 #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
162 #define EG_SH 16 /* 16.16 fixed point (envelope generator timing) */
163 #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
164 #define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
165
166 #define FREQ_MASK ((1<<FREQ_SH)-1)
167
168 #define MAXOUT (+32767)
169 #define MINOUT (-32768)
170
171 /* envelope generator */
172 #define ENV_BITS 10
173 #define ENV_LEN (1<<ENV_BITS)
174 #define ENV_STEP (128.0/ENV_LEN)
175
176 #define MAX_ATT_INDEX (ENV_LEN-1) /* 1023 */
177 #define MIN_ATT_INDEX (0) /* 0 */
178
179 #define EG_ATT 4
180 #define EG_DEC 3
181 #define EG_SUS 2
182 #define EG_REL 1
183 #define EG_OFF 0
184
185 /* operator unit */
186 #define SIN_BITS 10
187 #define SIN_LEN (1<<SIN_BITS)
188 #define SIN_MASK (SIN_LEN-1)
189
190 #define TL_RES_LEN (256) /* 8 bits addressing (real chip) */
191
192 /* TL_TAB_LEN is calculated as:
193 * 13 - sinus amplitude bits (Y axis)
194 * 2 - sinus sign bit (Y axis)
195 * TL_RES_LEN - sinus resolution (X axis)
196 */
197 #define TL_TAB_LEN (13*2*TL_RES_LEN)
198 static signed int tl_tab[TL_TAB_LEN];
199
200 #define ENV_QUIET (TL_TAB_LEN>>3)
201
202 /* sin waveform table in 'decibel' scale */
203 static unsigned int sin_tab[SIN_LEN];
204
205 /* sustain level table (3dB per step) */
206 /* bit0, bit1, bit2, bit3, bit4, bit5, bit6 */
207 /* 1, 2, 4, 8, 16, 32, 64 (value)*/
208 /* 0.75, 1.5, 3, 6, 12, 24, 48 (dB)*/
209
210 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
211 /* attenuation value (10 bits) = (SL << 2) << 3 */
212 #define SC(db) (UINT32) ( db * (4.0/ENV_STEP) )
213 static const UINT32 sl_table[16]={
214 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
215 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
216 };
217 #undef SC
218
219
220 #define RATE_STEPS (8)
221 static const UINT8 eg_inc[19*RATE_STEPS]={
222
223 /*cycle:0 1 2 3 4 5 6 7*/
224
225 /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..11 0 (increment by 0 or 1) */
226 /* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..11 1 */
227 /* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..11 2 */
228 /* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..11 3 */
229
230 /* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 12 0 (increment by 1) */
231 /* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 12 1 */
232 /* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 12 2 */
233 /* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 12 3 */
234
235 /* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 13 0 (increment by 2) */
236 /* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 13 1 */
237 /*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 13 2 */
238 /*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 13 3 */
239
240 /*12 */ 4,4, 4,4, 4,4, 4,4, /* rate 14 0 (increment by 4) */
241 /*13 */ 4,4, 4,8, 4,4, 4,8, /* rate 14 1 */
242 /*14 */ 4,8, 4,8, 4,8, 4,8, /* rate 14 2 */
243 /*15 */ 4,8, 8,8, 4,8, 8,8, /* rate 14 3 */
244
245 /*16 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */
246 /*17 */ 16,16,16,16,16,16,16,16, /* rates 15 2, 15 3 for attack */
247 /*18 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
248 };
249
250
251 #define O(a) (a*RATE_STEPS)
252
253 /*note that there is no O(17) in this table - it's directly in the code */
254 static const UINT8 eg_rate_select2612[32+64+32]={ /* Envelope Generator rates (32 + 64 rates + 32 RKS) */
255 /* 32 infinite time rates (same as Rate 0) */
256 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
257 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
258 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
259 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
260
261 /* rates 00-11 */
262 /*
263 O( 0),O( 1),O( 2),O( 3),
264 O( 0),O( 1),O( 2),O( 3),
265 */
266 O(18),O(18),O( 0),O( 0),
267 O( 0),O( 0),O( 2),O( 2), // Nemesis's tests
268
269 O( 0),O( 1),O( 2),O( 3),
270 O( 0),O( 1),O( 2),O( 3),
271 O( 0),O( 1),O( 2),O( 3),
272 O( 0),O( 1),O( 2),O( 3),
273 O( 0),O( 1),O( 2),O( 3),
274 O( 0),O( 1),O( 2),O( 3),
275 O( 0),O( 1),O( 2),O( 3),
276 O( 0),O( 1),O( 2),O( 3),
277 O( 0),O( 1),O( 2),O( 3),
278 O( 0),O( 1),O( 2),O( 3),
279
280 /* rate 12 */
281 O( 4),O( 5),O( 6),O( 7),
282
283 /* rate 13 */
284 O( 8),O( 9),O(10),O(11),
285
286 /* rate 14 */
287 O(12),O(13),O(14),O(15),
288
289 /* rate 15 */
290 O(16),O(16),O(16),O(16),
291
292 /* 32 dummy rates (same as 15 3) */
293 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
294 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
295 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
296 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
297
298 };
299 #undef O
300
301 /*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15*/
302 /*shift 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0 */
303 /*mask 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0, 0 */
304
305 #define O(a) (a*1)
306 static const UINT8 eg_rate_shift[32+64+32]={ /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */
307 /* 32 infinite time rates */
308 /* O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
309 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
310 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
311 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), */
312
313 /* fixed (should be the same as rate 0, even if it makes no difference since increment value is 0 for these rates) */
314 O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
315 O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
316 O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
317 O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),
318
319 /* rates 00-11 */
320 O(11),O(11),O(11),O(11),
321 O(10),O(10),O(10),O(10),
322 O( 9),O( 9),O( 9),O( 9),
323 O( 8),O( 8),O( 8),O( 8),
324 O( 7),O( 7),O( 7),O( 7),
325 O( 6),O( 6),O( 6),O( 6),
326 O( 5),O( 5),O( 5),O( 5),
327 O( 4),O( 4),O( 4),O( 4),
328 O( 3),O( 3),O( 3),O( 3),
329 O( 2),O( 2),O( 2),O( 2),
330 O( 1),O( 1),O( 1),O( 1),
331 O( 0),O( 0),O( 0),O( 0),
332
333 /* rate 12 */
334 O( 0),O( 0),O( 0),O( 0),
335
336 /* rate 13 */
337 O( 0),O( 0),O( 0),O( 0),
338
339 /* rate 14 */
340 O( 0),O( 0),O( 0),O( 0),
341
342 /* rate 15 */
343 O( 0),O( 0),O( 0),O( 0),
344
345 /* 32 dummy rates (same as 15 3) */
346 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
347 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
348 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
349 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0)
350
351 };
352 #undef O
353
354 static const UINT8 dt_tab[4 * 32]={
355 /* this is YM2151 and YM2612 phase increment data (in 10.10 fixed point format)*/
356 /* FD=0 */
357 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
358 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
359 /* FD=1 */
360 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
361 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
362 /* FD=2 */
363 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
364 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
365 /* FD=3 */
366 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
367 8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
368 };
369
370
371 /* OPN key frequency number -> key code follow table */
372 /* fnum higher 4bit -> keycode lower 2bit */
373 static const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
374
375
376 /* 8 LFO speed parameters */
377 /* each value represents number of samples that one LFO level will last for */
378 static const UINT32 lfo_samples_per_step[8] = {108, 77, 71, 67, 62, 44, 8, 5};
379
380
381
382 /*There are 4 different LFO AM depths available, they are:
383 0 dB, 1.4 dB, 5.9 dB, 11.8 dB
384 Here is how it is generated (in EG steps):
385
386 11.8 dB = 0, 2, 4, 6, 8, 10,12,14,16...126,126,124,122,120,118,....4,2,0
387 5.9 dB = 0, 1, 2, 3, 4, 5, 6, 7, 8....63, 63, 62, 61, 60, 59,.....2,1,0
388 1.4 dB = 0, 0, 0, 0, 1, 1, 1, 1, 2,...15, 15, 15, 15, 14, 14,.....0,0,0
389
390 (1.4 dB is losing precision as you can see)
391
392 It's implemented as generator from 0..126 with step 2 then a shift
393 right N times, where N is:
394 8 for 0 dB
395 3 for 1.4 dB
396 1 for 5.9 dB
397 0 for 11.8 dB
398 */
399 static const UINT8 lfo_ams_depth_shift[4] = {8, 3, 1, 0};
400
401
402
403 /*There are 8 different LFO PM depths available, they are:
404 0, 3.4, 6.7, 10, 14, 20, 40, 80 (cents)
405
406 Modulation level at each depth depends on F-NUMBER bits: 4,5,6,7,8,9,10
407 (bits 8,9,10 = FNUM MSB from OCT/FNUM register)
408
409 Here we store only first quarter (positive one) of full waveform.
410 Full table (lfo_pm_table) containing all 128 waveforms is build
411 at run (init) time.
412
413 One value in table below represents 4 (four) basic LFO steps
414 (1 PM step = 4 AM steps).
415
416 For example:
417 at LFO SPEED=0 (which is 108 samples per basic LFO step)
418 one value from "lfo_pm_output" table lasts for 432 consecutive
419 samples (4*108=432) and one full LFO waveform cycle lasts for 13824
420 samples (32*432=13824; 32 because we store only a quarter of whole
421 waveform in the table below)
422 */
423 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 */
424 /* FNUM BIT 4: 000 0001xxxx */
425 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
426 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
427 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
428 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
429 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0},
430 /* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0},
431 /* DEPTH 6 */ {0, 0, 0, 0, 0, 0, 0, 0},
432 /* DEPTH 7 */ {0, 0, 0, 0, 1, 1, 1, 1},
433
434 /* FNUM BIT 5: 000 0010xxxx */
435 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
436 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
437 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
438 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
439 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0},
440 /* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0},
441 /* DEPTH 6 */ {0, 0, 0, 0, 1, 1, 1, 1},
442 /* DEPTH 7 */ {0, 0, 1, 1, 2, 2, 2, 3},
443
444 /* FNUM BIT 6: 000 0100xxxx */
445 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
446 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
447 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
448 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
449 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 1},
450 /* DEPTH 5 */ {0, 0, 0, 0, 1, 1, 1, 1},
451 /* DEPTH 6 */ {0, 0, 1, 1, 2, 2, 2, 3},
452 /* DEPTH 7 */ {0, 0, 2, 3, 4, 4, 5, 6},
453
454 /* FNUM BIT 7: 000 1000xxxx */
455 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
456 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
457 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 1, 1},
458 /* DEPTH 3 */ {0, 0, 0, 0, 1, 1, 1, 1},
459 /* DEPTH 4 */ {0, 0, 0, 1, 1, 1, 1, 2},
460 /* DEPTH 5 */ {0, 0, 1, 1, 2, 2, 2, 3},
461 /* DEPTH 6 */ {0, 0, 2, 3, 4, 4, 5, 6},
462 /* DEPTH 7 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
463
464 /* FNUM BIT 8: 001 0000xxxx */
465 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
466 /* DEPTH 1 */ {0, 0, 0, 0, 1, 1, 1, 1},
467 /* DEPTH 2 */ {0, 0, 0, 1, 1, 1, 2, 2},
468 /* DEPTH 3 */ {0, 0, 1, 1, 2, 2, 3, 3},
469 /* DEPTH 4 */ {0, 0, 1, 2, 2, 2, 3, 4},
470 /* DEPTH 5 */ {0, 0, 2, 3, 4, 4, 5, 6},
471 /* DEPTH 6 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
472 /* DEPTH 7 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
473
474 /* FNUM BIT 9: 010 0000xxxx */
475 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
476 /* DEPTH 1 */ {0, 0, 0, 0, 2, 2, 2, 2},
477 /* DEPTH 2 */ {0, 0, 0, 2, 2, 2, 4, 4},
478 /* DEPTH 3 */ {0, 0, 2, 2, 4, 4, 6, 6},
479 /* DEPTH 4 */ {0, 0, 2, 4, 4, 4, 6, 8},
480 /* DEPTH 5 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
481 /* DEPTH 6 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
482 /* DEPTH 7 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30},
483
484 /* FNUM BIT10: 100 0000xxxx */
485 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
486 /* DEPTH 1 */ {0, 0, 0, 0, 4, 4, 4, 4},
487 /* DEPTH 2 */ {0, 0, 0, 4, 4, 4, 8, 8},
488 /* DEPTH 3 */ {0, 0, 4, 4, 8, 8, 0xc, 0xc},
489 /* DEPTH 4 */ {0, 0, 4, 8, 8, 8, 0xc,0x10},
490 /* DEPTH 5 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
491 /* DEPTH 6 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30},
492 /* DEPTH 7 */ {0, 0,0x20,0x30,0x40,0x40,0x50,0x60},
493
494 };
495
496 /* all 128 LFO PM waveforms */
497 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 */
498
499 /* register number to channel number , slot offset */
500 #define OPN_CHAN(N) (N&3)
501 #define OPN_SLOT(N) ((N>>2)&3)
502
503 /* slot number */
504 #define SLOT1 0
505 #define SLOT2 2
506 #define SLOT3 1
507 #define SLOT4 3
508
509 /* bit0 = Right enable , bit1 = Left enable */
510 #define OUTD_RIGHT 1
511 #define OUTD_LEFT 2
512 #define OUTD_CENTER 3
513
514
515 /* save output as raw 16-bit sample */
516 /* #define SAVE_SAMPLE */
517
518 #ifdef SAVE_SAMPLE
519 static FILE *sample[1];
520 #if 1 /*save to MONO file */
521 #define SAVE_ALL_CHANNELS \
522 { signed int pom = lt; \
523 fputc((unsigned short)pom&0xff,sample[0]); \
524 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
525 }
526 #else /*save to STEREO file */
527 #define SAVE_ALL_CHANNELS \
528 { signed int pom = lt; \
529 fputc((unsigned short)pom&0xff,sample[0]); \
530 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
531 pom = rt; \
532 fputc((unsigned short)pom&0xff,sample[0]); \
533 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
534 }
535 #endif
536 #endif
537
538
539 /* struct describing a single operator (SLOT) */
540 typedef struct
541 {
542 INT32 *DT; /* detune :dt_tab[DT] */
543 UINT8 KSR; /* key scale rate :3-KSR */
544 UINT32 ar; /* attack rate */
545 UINT32 d1r; /* decay rate */
546 UINT32 d2r; /* sustain rate */
547 UINT32 rr; /* release rate */
548 UINT8 ksr; /* key scale rate :kcode>>(3-KSR) */
549 UINT32 mul; /* multiple :ML_TABLE[ML] */
550
551 /* Phase Generator */
552 UINT32 phase; /* phase counter */
553 INT32 Incr; /* phase step */
554
555 /* Envelope Generator */
556 UINT8 state; /* phase type */
557 UINT32 tl; /* total level: TL << 3 */
558 INT32 volume; /* envelope counter */
559 UINT32 sl; /* sustain level:sl_table[SL] */
560 UINT32 vol_out; /* current output from EG circuit (without AM from LFO) */
561
562 UINT8 eg_sh_ar; /* (attack state) */
563 UINT8 eg_sel_ar; /* (attack state) */
564 UINT8 eg_sh_d1r; /* (decay state) */
565 UINT8 eg_sel_d1r; /* (decay state) */
566 UINT8 eg_sh_d2r; /* (sustain state) */
567 UINT8 eg_sel_d2r; /* (sustain state) */
568 UINT8 eg_sh_rr; /* (release state) */
569 UINT8 eg_sel_rr; /* (release state) */
570
571 UINT8 ssg; /* SSG-EG waveform */
572 UINT8 ssgn; /* SSG-EG negated output */
573
574 UINT8 key; /* 0=last key was KEY OFF, 1=KEY ON */
575
576 /* LFO */
577 UINT32 AMmask; /* AM enable flag */
578
579 } FM_SLOT;
580
581 typedef struct
582 {
583 FM_SLOT SLOT[4]; /* four SLOTs (operators) */
584
585 UINT8 ALGO; /* algorithm */
586 UINT8 FB; /* feedback shift */
587 INT32 op1_out[2]; /* op1 output for feedback */
588
589 INT32 *connect1; /* SLOT1 output pointer */
590 INT32 *connect3; /* SLOT3 output pointer */
591 INT32 *connect2; /* SLOT2 output pointer */
592 INT32 *connect4; /* SLOT4 output pointer */
593
594 INT32 *mem_connect;/* where to put the delayed sample (MEM) */
595 INT32 mem_value; /* delayed sample (MEM) value */
596
597 INT32 pms; /* channel PMS */
598 UINT8 ams; /* channel AMS */
599
600 UINT32 fc; /* fnum,blk:adjusted to sample rate */
601 UINT8 kcode; /* key code: */
602 UINT32 block_fnum; /* current blk/fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
603 UINT8 Muted;
604 UINT8 *IsVGMInit;
605 } FM_CH;
606
607
608 typedef struct
609 {
610 //running_device *device;
611 void * param; /* this chip parameter */
612 double freqbase; /* frequency base */
613 int timer_prescaler; /* timer prescaler */
614 UINT8 irq; /* interrupt level */
615 UINT8 irqmask; /* irq mask */
616 #if FM_BUSY_FLAG_SUPPORT
617 TIME_TYPE busy_expiry_time; /* expiry time of the busy status */
618 #endif
619 UINT32 clock; /* master clock (Hz) */
620 UINT32 rate; /* sampling rate (Hz) */
621 UINT8 address; /* address register */
622 UINT8 status; /* status flag */
623 UINT32 mode; /* mode CSM / 3SLOT */
624 UINT8 fn_h; /* freq latch */
625 UINT8 prescaler_sel; /* prescaler selector */
626 INT32 TA; /* timer a */
627 INT32 TAC; /* timer a counter */
628 UINT8 TB; /* timer b */
629 INT32 TBC; /* timer b counter */
630 /* local time tables */
631 INT32 dt_tab[8][32]; /* DeTune table */
632 /* Extention Timer and IRQ handler */
633 FM_TIMERHANDLER timer_handler;
634 FM_IRQHANDLER IRQ_Handler;
635 const ssg_callbacks *SSG;
636 } FM_ST;
637
638
639
640 /***********************************************************/
641 /* OPN unit */
642 /***********************************************************/
643
644 /* OPN 3slot struct */
645 typedef struct
646 {
647 UINT32 fc[3]; /* fnum3,blk3: calculated */
648 UINT8 fn_h; /* freq3 latch */
649 UINT8 kcode[3]; /* key code */
650 UINT32 block_fnum[3]; /* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
651 UINT8 key_csm; /* CSM mode Key-ON flag */
652 } FM_3SLOT;
653
654 /* OPN/A/B common state */
655 typedef struct
656 {
657 UINT8 type; /* chip type */
658 FM_ST ST; /* general state */
659 FM_3SLOT SL3; /* 3 slot mode state */
660 FM_CH *P_CH; /* pointer of CH */
661 unsigned int pan[6*2]; /* fm channels output masks (0xffffffff = enable) */
662
663 UINT32 eg_cnt; /* global envelope generator counter */
664 UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/144/3 */
665 UINT32 eg_timer_add; /* step of eg_timer */
666 UINT32 eg_timer_overflow;/* envelope generator timer overlfows every 3 samples (on real chip) */
667
668
669 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
670 but LFO works with one more bit of a precision so we really need 4096 elements */
671 UINT32 fn_table[4096]; /* fnumber->increment counter */
672 UINT32 fn_max; /* maximal phase increment (used for phase overflow) */
673
674 /* LFO */
675 UINT8 lfo_cnt; /* current LFO phase (out of 128) */
676 UINT32 lfo_timer; /* current LFO phase runs at LFO frequency */
677 UINT32 lfo_timer_add; /* step of lfo_timer */
678 UINT32 lfo_timer_overflow; /* LFO timer overflows every N samples (depends on LFO frequency) */
679 UINT32 LFO_AM; /* current LFO AM step */
680 UINT32 LFO_PM; /* current LFO PM step */
681
682 INT32 m2,c1,c2; /* Phase Modulation input for operators 2,3,4 */
683 INT32 mem; /* one sample delay memory */
684 INT32 out_fm[6]; /* outputs of working channels */
685
686 UINT8 *IsVGMInit;
687 } FM_OPN;
688
689 /* here's the virtual YM2612 */
690 typedef struct
691 {
692 UINT8 REGS[512]; /* registers */
693 FM_OPN OPN; /* OPN state */
694 FM_CH CH[6]; /* channel state */
695 UINT8 addr_A1; /* address line A1 */
696
697 /* dac output (YM2612) */
698 //int dacen;
699 UINT8 dacen;
700 UINT8 dac_test;
701 INT32 dacout;
702 UINT8 MuteDAC;
703
704 UINT8 WaveOutMode;
705 INT32 WaveL;
706 INT32 WaveR;
707
708 UINT8 PseudoSt;
709 } YM2612;
710
711 /* log output level */
712 #define LOG_ERR 3 /* ERROR */
713 #define LOG_WAR 2 /* WARNING */
714 #define LOG_INF 1 /* INFORMATION */
715 #define LOG_LEVEL LOG_INF
716
717 #ifndef __RAINE__
718 #define LOG(n,x) do { if( (n)>=LOG_LEVEL ) logerror x; } while (0)
719 #endif
720
721 /* limitter */
722 #define Limit(val, max,min) { \
723 if ( val > max ) val = max; \
724 else if ( val < min ) val = min; \
725 }
726
727 /*#include <stdio.h>
728 static FILE* hFile;
729 static UINT32 FileSample;*/
730
731 /* status set and IRQ handling */
FM_STATUS_SET(FM_ST * ST,int flag)732 INLINE void FM_STATUS_SET(FM_ST *ST,int flag)
733 {
734 /* set status flag */
735 ST->status |= flag;
736 if ( !(ST->irq) && (ST->status & ST->irqmask) )
737 {
738 ST->irq = 1;
739 /* callback user interrupt handler (IRQ is OFF to ON) */
740 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->param,1);
741 }
742 }
743
744 /* status reset and IRQ handling */
FM_STATUS_RESET(FM_ST * ST,int flag)745 INLINE void FM_STATUS_RESET(FM_ST *ST,int flag)
746 {
747 /* reset status flag */
748 ST->status &=~flag;
749 if ( (ST->irq) && !(ST->status & ST->irqmask) )
750 {
751 ST->irq = 0;
752 /* callback user interrupt handler (IRQ is ON to OFF) */
753 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->param,0);
754 }
755 }
756
757 /* IRQ mask set */
FM_IRQMASK_SET(FM_ST * ST,int flag)758 INLINE void FM_IRQMASK_SET(FM_ST *ST,int flag)
759 {
760 ST->irqmask = flag;
761 /* IRQ handling check */
762 FM_STATUS_SET(ST,0);
763 FM_STATUS_RESET(ST,0);
764 }
765
FM_KEYON(FM_OPN * OPN,FM_CH * CH,int s)766 INLINE void FM_KEYON(FM_OPN *OPN, FM_CH *CH , int s )
767 {
768 FM_SLOT *SLOT = &CH->SLOT[s];
769
770 // Note by Valley Bell:
771 // I assume that the CSM mode shouldn't affect channels
772 // other than FM3, so I added a check for it here.
773 if( !SLOT->key && (!OPN->SL3.key_csm || CH == &OPN->P_CH[3]))
774 {
775 /* restart Phase Generator */
776 SLOT->phase = 0;
777
778 /* reset SSG-EG inversion flag */
779 SLOT->ssgn = 0;
780
781 if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/)
782 {
783 SLOT->state = (SLOT->volume <= MIN_ATT_INDEX) ? ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC) : EG_ATT;
784 }
785 else
786 {
787 /* force attenuation level to 0 */
788 SLOT->volume = MIN_ATT_INDEX;
789
790 /* directly switch to Decay (or Sustain) */
791 SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
792 }
793
794 /* recalculate EG output */
795 if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)))
796 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
797 else
798 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
799 }
800
801 SLOT->key = 1;
802 }
803
FM_KEYOFF(FM_OPN * OPN,FM_CH * CH,int s)804 INLINE void FM_KEYOFF(FM_OPN *OPN, FM_CH *CH , int s )
805 {
806 FM_SLOT *SLOT = &CH->SLOT[s];
807
808 if (SLOT->key && (!OPN->SL3.key_csm || CH == &OPN->P_CH[3]))
809 {
810 if (*OPN->IsVGMInit) // workaround for VGMs trimmed with VGMTool
811 {
812 SLOT->state = EG_OFF;
813 SLOT->volume = MAX_ATT_INDEX;
814 SLOT->vol_out= MAX_ATT_INDEX;
815 }
816 else if (SLOT->state>EG_REL)
817 {
818 SLOT->state = EG_REL; /* phase -> Release */
819
820 /* SSG-EG specific update */
821 if (SLOT->ssg&0x08)
822 {
823 /* convert EG attenuation level */
824 if (SLOT->ssgn ^ (SLOT->ssg&0x04))
825 SLOT->volume = (0x200 - SLOT->volume);
826
827 /* force EG attenuation level */
828 if (SLOT->volume >= 0x200)
829 {
830 SLOT->volume = MAX_ATT_INDEX;
831 SLOT->state = EG_OFF;
832 }
833
834 /* recalculate EG output */
835 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
836 }
837 }
838 }
839
840 SLOT->key = 0;
841 }
842
FM_KEYON_CSM(FM_OPN * OPN,FM_CH * CH,int s)843 INLINE void FM_KEYON_CSM(FM_OPN *OPN, FM_CH *CH , int s )
844 {
845 FM_SLOT *SLOT = &CH->SLOT[s];
846
847 if( !SLOT->key && !OPN->SL3.key_csm)
848 {
849 /* restart Phase Generator */
850 SLOT->phase = 0;
851
852 /* reset SSG-EG inversion flag */
853 SLOT->ssgn = 0;
854
855 if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/)
856 {
857 SLOT->state = (SLOT->volume <= MIN_ATT_INDEX) ? ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC) : EG_ATT;
858 }
859 else
860 {
861 /* force attenuation level to 0 */
862 SLOT->volume = MIN_ATT_INDEX;
863
864 /* directly switch to Decay (or Sustain) */
865 SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
866 }
867
868 /* recalculate EG output */
869 if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)))
870 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
871 else
872 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
873 }
874 }
875
FM_KEYOFF_CSM(FM_CH * CH,int s)876 INLINE void FM_KEYOFF_CSM(FM_CH *CH , int s )
877 {
878 FM_SLOT *SLOT = &CH->SLOT[s];
879 if (!SLOT->key)
880 {
881 if (*CH->IsVGMInit)
882 {
883 SLOT->state = EG_OFF;
884 SLOT->volume = MAX_ATT_INDEX;
885 SLOT->vol_out= MAX_ATT_INDEX;
886 }
887 else if (SLOT->state>EG_REL)
888 {
889 SLOT->state = EG_REL; /* phase -> Release */
890
891 /* SSG-EG specific update */
892 if (SLOT->ssg&0x08)
893 {
894 /* convert EG attenuation level */
895 if (SLOT->ssgn ^ (SLOT->ssg&0x04))
896 SLOT->volume = (0x200 - SLOT->volume);
897
898 /* force EG attenuation level */
899 if (SLOT->volume >= 0x200)
900 {
901 SLOT->volume = MAX_ATT_INDEX;
902 SLOT->state = EG_OFF;
903 }
904
905 /* recalculate EG output */
906 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
907 }
908 }
909 }
910 }
911
912 /* OPN Mode Register Write */
set_timers(FM_OPN * OPN,FM_ST * ST,void * n,int v)913 INLINE void set_timers( FM_OPN *OPN, FM_ST *ST, void *n, int v )
914 {
915 /* b7 = CSM MODE */
916 /* b6 = 3 slot mode */
917 /* b5 = reset b */
918 /* b4 = reset a */
919 /* b3 = timer enable b */
920 /* b2 = timer enable a */
921 /* b1 = load b */
922 /* b0 = load a */
923
924 if ((OPN->ST.mode ^ v) & 0xC0)
925 {
926 /* phase increment need to be recalculated */
927 OPN->P_CH[2].SLOT[SLOT1].Incr=-1;
928
929 /* CSM mode disabled and CSM key ON active*/
930 if (((v & 0xC0) != 0x80) && OPN->SL3.key_csm)
931 {
932 /* CSM Mode Key OFF (verified by Nemesis on real hardware) */
933 FM_KEYOFF_CSM(&OPN->P_CH[2],SLOT1);
934 FM_KEYOFF_CSM(&OPN->P_CH[2],SLOT2);
935 FM_KEYOFF_CSM(&OPN->P_CH[2],SLOT3);
936 FM_KEYOFF_CSM(&OPN->P_CH[2],SLOT4);
937 OPN->SL3.key_csm = 0;
938 }
939 }
940
941 // reset Timer b flag
942 if( v & 0x20 )
943 FM_STATUS_RESET(ST,0x02);
944 // reset Timer a flag
945 if( v & 0x10 )
946 FM_STATUS_RESET(ST,0x01);
947 // load b
948 if ((v&2) && !(ST->mode&2))
949 {
950 ST->TBC = ( 256-ST->TB)<<4;
951 /* External timer handler */
952 if (ST->timer_handler) (ST->timer_handler)(n,1,ST->TBC * ST->timer_prescaler,ST->clock);
953 }
954 // load a
955 if ((v&1) && !(ST->mode&1))
956 {
957 ST->TAC = (1024-ST->TA);
958 /* External timer handler */
959 if (ST->timer_handler) (ST->timer_handler)(n,0,ST->TAC * ST->timer_prescaler,ST->clock);
960 ST->TAC *= 4096;
961 }
962
963 ST->mode = v;
964 }
965
966
967 /* Timer A Overflow */
TimerAOver(FM_ST * ST)968 INLINE void TimerAOver(FM_ST *ST)
969 {
970 /* set status (if enabled) */
971 if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
972 /* clear or reload the counter */
973 ST->TAC = (1024-ST->TA);
974 if (ST->timer_handler) (ST->timer_handler)(ST->param,0,ST->TAC * ST->timer_prescaler,ST->clock);
975 ST->TAC *= 4096;
976 }
977 /* Timer B Overflow */
TimerBOver(FM_ST * ST)978 INLINE void TimerBOver(FM_ST *ST)
979 {
980 /* set status (if enabled) */
981 if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
982 /* clear or reload the counter */
983 ST->TBC = ( 256-ST->TB)<<4;
984 if (ST->timer_handler) (ST->timer_handler)(ST->param,1,ST->TBC * ST->timer_prescaler,ST->clock);
985 }
986
987
988 #if FM_INTERNAL_TIMER
989 /* ----- internal timer mode , update timer */
990 // Valley Bell: defines fixed
991
992 /* ---------- calculate timer A ---------- */
993 #define INTERNAL_TIMER_A(ST,CSM_CH) \
994 { \
995 if( (ST)->TAC && ((ST)->timer_handler==0) ) \
996 if( ((ST)->TAC -= (int)((ST)->freqbase*4096)) <= 0 ) \
997 { \
998 TimerAOver( ST ); \
999 /* CSM mode total level latch and auto key on */ \
1000 if( (ST)->mode & 0x80 ) \
1001 CSMKeyControll( OPN, CSM_CH ); \
1002 } \
1003 }
1004 /* ---------- calculate timer B ---------- */
1005 #define INTERNAL_TIMER_B(ST,step) \
1006 { \
1007 if( (ST)->TBC && ((ST)->timer_handler==0) ) \
1008 if( ((ST)->TBC -= (int)((ST)->freqbase*4096*step)) <= 0 ) \
1009 TimerBOver( ST ); \
1010 }
1011 #else /* FM_INTERNAL_TIMER */
1012 /* external timer mode */
1013 #define INTERNAL_TIMER_A(ST,CSM_CH)
1014 #define INTERNAL_TIMER_B(ST,step)
1015 #endif /* FM_INTERNAL_TIMER */
1016
1017
1018
1019 #if FM_BUSY_FLAG_SUPPORT
1020 #define FM_BUSY_CLEAR(ST) ((ST)->busy_expiry_time = UNDEFINED_TIME)
FM_STATUS_FLAG(FM_ST * ST)1021 INLINE UINT8 FM_STATUS_FLAG(FM_ST *ST)
1022 {
1023 if( COMPARE_TIMES(ST->busy_expiry_time, UNDEFINED_TIME) != 0 )
1024 {
1025 if (COMPARE_TIMES(ST->busy_expiry_time, FM_GET_TIME_NOW(ST->device->machine)) > 0)
1026 return ST->status | 0x80; /* with busy */
1027 /* expire */
1028 FM_BUSY_CLEAR(ST);
1029 }
1030 return ST->status;
1031 }
FM_BUSY_SET(FM_ST * ST,int busyclock)1032 INLINE void FM_BUSY_SET(FM_ST *ST,int busyclock )
1033 {
1034 TIME_TYPE expiry_period = MULTIPLY_TIME_BY_INT(ATTOTIME_IN_HZ(ST->clock), busyclock * ST->timer_prescaler);
1035 ST->busy_expiry_time = ADD_TIMES(FM_GET_TIME_NOW(ST->device->machine), expiry_period);
1036 }
1037 #else
1038 #define FM_STATUS_FLAG(ST) ((ST)->status)
1039 #define FM_BUSY_SET(ST,bclock) {}
1040 #define FM_BUSY_CLEAR(ST) {}
1041 #endif
1042
1043
1044 /* set algorithm connection */
setup_connection(FM_OPN * OPN,FM_CH * CH,int ch)1045 INLINE void setup_connection( FM_OPN *OPN, FM_CH *CH, int ch )
1046 {
1047 INT32 *carrier = &OPN->out_fm[ch];
1048
1049 INT32 **om1 = &CH->connect1;
1050 INT32 **om2 = &CH->connect3;
1051 INT32 **oc1 = &CH->connect2;
1052
1053 INT32 **memc = &CH->mem_connect;
1054
1055 switch( CH->ALGO )
1056 {
1057 case 0:
1058 /* M1---C1---MEM---M2---C2---OUT */
1059 *om1 = &OPN->c1;
1060 *oc1 = &OPN->mem;
1061 *om2 = &OPN->c2;
1062 *memc= &OPN->m2;
1063 break;
1064 case 1:
1065 /* M1------+-MEM---M2---C2---OUT */
1066 /* C1-+ */
1067 *om1 = &OPN->mem;
1068 *oc1 = &OPN->mem;
1069 *om2 = &OPN->c2;
1070 *memc= &OPN->m2;
1071 break;
1072 case 2:
1073 /* M1-----------------+-C2---OUT */
1074 /* C1---MEM---M2-+ */
1075 *om1 = &OPN->c2;
1076 *oc1 = &OPN->mem;
1077 *om2 = &OPN->c2;
1078 *memc= &OPN->m2;
1079 break;
1080 case 3:
1081 /* M1---C1---MEM------+-C2---OUT */
1082 /* M2-+ */
1083 *om1 = &OPN->c1;
1084 *oc1 = &OPN->mem;
1085 *om2 = &OPN->c2;
1086 *memc= &OPN->c2;
1087 break;
1088 case 4:
1089 /* M1---C1-+-OUT */
1090 /* M2---C2-+ */
1091 /* MEM: not used */
1092 *om1 = &OPN->c1;
1093 *oc1 = carrier;
1094 *om2 = &OPN->c2;
1095 *memc= &OPN->mem; /* store it anywhere where it will not be used */
1096 break;
1097 case 5:
1098 /* +----C1----+ */
1099 /* M1-+-MEM---M2-+-OUT */
1100 /* +----C2----+ */
1101 *om1 = 0; /* special mark */
1102 *oc1 = carrier;
1103 *om2 = carrier;
1104 *memc= &OPN->m2;
1105 break;
1106 case 6:
1107 /* M1---C1-+ */
1108 /* M2-+-OUT */
1109 /* C2-+ */
1110 /* MEM: not used */
1111 *om1 = &OPN->c1;
1112 *oc1 = carrier;
1113 *om2 = carrier;
1114 *memc= &OPN->mem; /* store it anywhere where it will not be used */
1115 break;
1116 case 7:
1117 /* M1-+ */
1118 /* C1-+-OUT */
1119 /* M2-+ */
1120 /* C2-+ */
1121 /* MEM: not used*/
1122 *om1 = carrier;
1123 *oc1 = carrier;
1124 *om2 = carrier;
1125 *memc= &OPN->mem; /* store it anywhere where it will not be used */
1126 break;
1127 }
1128
1129 CH->connect4 = carrier;
1130 }
1131
1132 /* set detune & multiple */
set_det_mul(FM_ST * ST,FM_CH * CH,FM_SLOT * SLOT,int v)1133 INLINE void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
1134 {
1135 SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1;
1136 SLOT->DT = ST->dt_tab[(v>>4)&7];
1137 CH->SLOT[SLOT1].Incr=-1;
1138 }
1139
1140 /* set total level */
set_tl(FM_CH * CH,FM_SLOT * SLOT,int v)1141 INLINE void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v)
1142 {
1143 SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */
1144
1145 /* recalculate EG output */
1146 if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)) && (SLOT->state > EG_REL))
1147 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
1148 else
1149 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1150 }
1151
1152 /* set attack rate & key scale */
set_ar_ksr(UINT8 type,FM_CH * CH,FM_SLOT * SLOT,int v)1153 INLINE void set_ar_ksr(UINT8 type, FM_CH *CH,FM_SLOT *SLOT,int v)
1154 {
1155 UINT8 old_KSR = SLOT->KSR;
1156
1157 SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1158
1159 SLOT->KSR = 3-(v>>6);
1160 if (SLOT->KSR != old_KSR)
1161 {
1162 CH->SLOT[SLOT1].Incr=-1;
1163 }
1164
1165 /* Even if it seems unnecessary, in some odd case, KSR and KC are both modified */
1166 /* and could result in SLOT->kc remaining unchanged. */
1167 /* In such case, AR values would not be recalculated despite SLOT->ar has changed */
1168 /* This fixes the introduction music of Batman & Robin (Eke-Eke) */
1169 if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/)
1170 {
1171 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1172 SLOT->eg_sel_ar = eg_rate_select2612[SLOT->ar + SLOT->ksr ];
1173 }
1174 else
1175 {
1176 SLOT->eg_sh_ar = 0;
1177 SLOT->eg_sel_ar = 18*RATE_STEPS; /* verified by Nemesis on real hardware */
1178 }
1179 }
1180
1181 /* set decay rate */
set_dr(UINT8 type,FM_SLOT * SLOT,int v)1182 INLINE void set_dr(UINT8 type, FM_SLOT *SLOT,int v)
1183 {
1184 SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1185
1186 SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
1187 SLOT->eg_sel_d1r= eg_rate_select2612[SLOT->d1r + SLOT->ksr];
1188 }
1189
1190 /* set sustain rate */
set_sr(UINT8 type,FM_SLOT * SLOT,int v)1191 INLINE void set_sr(UINT8 type, FM_SLOT *SLOT,int v)
1192 {
1193 SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1194
1195 SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
1196 SLOT->eg_sel_d2r= eg_rate_select2612[SLOT->d2r + SLOT->ksr];
1197 }
1198
1199 /* set release rate */
set_sl_rr(UINT8 type,FM_SLOT * SLOT,int v)1200 INLINE void set_sl_rr(UINT8 type, FM_SLOT *SLOT,int v)
1201 {
1202 SLOT->sl = sl_table[ v>>4 ];
1203
1204 /* check EG state changes */
1205 if ((SLOT->state == EG_DEC) && (SLOT->volume >= (INT32)(SLOT->sl)))
1206 SLOT->state = EG_SUS;
1207
1208 SLOT->rr = 34 + ((v&0x0f)<<2);
1209
1210 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
1211 SLOT->eg_sel_rr = eg_rate_select2612[SLOT->rr + SLOT->ksr];
1212 }
1213
1214 /* advance LFO to next sample */
advance_lfo(FM_OPN * OPN)1215 INLINE void advance_lfo(FM_OPN *OPN)
1216 {
1217 if (OPN->lfo_timer_overflow) /* LFO enabled ? */
1218 {
1219 /* increment LFO timer */
1220 OPN->lfo_timer += OPN->lfo_timer_add;
1221
1222 /* when LFO is enabled, one level will last for 108, 77, 71, 67, 62, 44, 8 or 5 samples */
1223 while (OPN->lfo_timer >= OPN->lfo_timer_overflow)
1224 {
1225 OPN->lfo_timer -= OPN->lfo_timer_overflow;
1226
1227 /* There are 128 LFO steps */
1228 OPN->lfo_cnt = ( OPN->lfo_cnt + 1 ) & 127;
1229
1230 // Valley Bell: Replaced old code (non-inverted triangle) with
1231 // the one from Genesis Plus GX 1.71.
1232 /* triangle (inverted) */
1233 /* AM: from 126 to 0 step -2, 0 to 126 step +2 */
1234 if (OPN->lfo_cnt<64)
1235 OPN->LFO_AM = (OPN->lfo_cnt ^ 63) << 1;
1236 else
1237 OPN->LFO_AM = (OPN->lfo_cnt & 63) << 1;
1238
1239 /* PM works with 4 times slower clock */
1240 OPN->LFO_PM = OPN->lfo_cnt >> 2;
1241 }
1242 }
1243 }
1244
advance_eg_channel(FM_OPN * OPN,FM_SLOT * SLOT)1245 INLINE void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
1246 {
1247 //unsigned int out;
1248 unsigned int i = 4; /* four operators per channel */
1249
1250 do
1251 {
1252 switch(SLOT->state)
1253 {
1254 case EG_ATT: /* attack phase */
1255 if (!(OPN->eg_cnt & ((1<<SLOT->eg_sh_ar)-1)))
1256 {
1257 /* update attenuation level */
1258 SLOT->volume += (~SLOT->volume * (eg_inc[SLOT->eg_sel_ar + ((OPN->eg_cnt>>SLOT->eg_sh_ar)&7)]))>>4;
1259
1260 /* check phase transition*/
1261 if (SLOT->volume <= MIN_ATT_INDEX)
1262 {
1263 SLOT->volume = MIN_ATT_INDEX;
1264 SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; /* special case where SL=0 */
1265 }
1266
1267 /* recalculate EG output */
1268 if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04))) /* SSG-EG Output Inversion */
1269 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
1270 else
1271 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1272 }
1273 break;
1274
1275 case EG_DEC: /* decay phase */
1276 if (!(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1)))
1277 {
1278 /* SSG EG type */
1279 if (SLOT->ssg&0x08)
1280 {
1281 /* update attenuation level */
1282 if (SLOT->volume < 0x200)
1283 {
1284 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1285
1286 /* recalculate EG output */
1287 if (SLOT->ssgn ^ (SLOT->ssg&0x04)) /* SSG-EG Output Inversion */
1288 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
1289 else
1290 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1291 }
1292
1293 }
1294 else
1295 {
1296 /* update attenuation level */
1297 SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1298
1299 /* recalculate EG output */
1300 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1301 }
1302
1303 /* check phase transition*/
1304 if (SLOT->volume >= (INT32)(SLOT->sl))
1305 SLOT->state = EG_SUS;
1306 }
1307 break;
1308
1309 case EG_SUS: /* sustain phase */
1310 if (!(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1)))
1311 {
1312 /* SSG EG type */
1313 if (SLOT->ssg&0x08)
1314 {
1315 /* update attenuation level */
1316 if (SLOT->volume < 0x200)
1317 {
1318 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1319
1320 /* recalculate EG output */
1321 if (SLOT->ssgn ^ (SLOT->ssg&0x04)) /* SSG-EG Output Inversion */
1322 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
1323 else
1324 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1325 }
1326 }
1327 else
1328 {
1329 /* update attenuation level */
1330 SLOT->volume += eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1331
1332 /* check phase transition*/
1333 if ( SLOT->volume >= MAX_ATT_INDEX )
1334 SLOT->volume = MAX_ATT_INDEX;
1335 /* do not change SLOT->state (verified on real chip) */
1336
1337 /* recalculate EG output */
1338 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1339 }
1340 }
1341 break;
1342
1343 case EG_REL: /* release phase */
1344 if (!(OPN->eg_cnt & ((1<<SLOT->eg_sh_rr)-1)))
1345 {
1346 /* SSG EG type */
1347 if (SLOT->ssg&0x08)
1348 {
1349 /* update attenuation level */
1350 if (SLOT->volume < 0x200)
1351 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)];
1352 /* check phase transition */
1353 if (SLOT->volume >= 0x200)
1354 {
1355 SLOT->volume = MAX_ATT_INDEX;
1356 SLOT->state = EG_OFF;
1357 }
1358 }
1359 else
1360 {
1361 /* update attenuation level */
1362 SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)];
1363
1364 /* check phase transition*/
1365 if (SLOT->volume >= MAX_ATT_INDEX)
1366 {
1367 SLOT->volume = MAX_ATT_INDEX;
1368 SLOT->state = EG_OFF;
1369 }
1370 }
1371
1372 /* recalculate EG output */
1373 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1374
1375 }
1376 break;
1377 }
1378
1379 // Valley Bell: These few lines are missing in Genesis Plus GX' ym2612 core file.
1380 // Disabling them fixes the SSG-EG.
1381 // Additional Note: Asterix and the Great Rescue: Level 1 sounds "better" with these lines,
1382 // but less accurate.
1383 /*out = ((UINT32)SLOT->volume);
1384
1385 // negate output (changes come from alternate bit, init comes from attack bit)
1386 if ((SLOT->ssg&0x08) && (SLOT->ssgn&2) && (SLOT->state > EG_REL))
1387 out ^= MAX_ATT_INDEX;
1388
1389 // we need to store the result here because we are going to change ssgn
1390 // in next instruction
1391 SLOT->vol_out = out + SLOT->tl;*/
1392
1393 SLOT++;
1394 i--;
1395 }while (i);
1396
1397 }
1398
1399 /* SSG-EG update process */
1400 /* The behavior is based upon Nemesis tests on real hardware */
1401 /* This is actually executed before each samples */
update_ssg_eg_channel(FM_SLOT * SLOT)1402 INLINE void update_ssg_eg_channel(FM_SLOT *SLOT)
1403 {
1404 unsigned int i = 4; /* four operators per channel */
1405
1406 do
1407 {
1408 /* detect SSG-EG transition */
1409 /* this is not required during release phase as the attenuation has been forced to MAX and output invert flag is not used */
1410 /* if an Attack Phase is programmed, inversion can occur on each sample */
1411 if ((SLOT->ssg & 0x08) && (SLOT->volume >= 0x200) && (SLOT->state > EG_REL))
1412 {
1413 if (SLOT->ssg & 0x01) /* bit 0 = hold SSG-EG */
1414 {
1415 /* set inversion flag */
1416 if (SLOT->ssg & 0x02)
1417 SLOT->ssgn = 4;
1418
1419 /* force attenuation level during decay phases */
1420 if ((SLOT->state != EG_ATT) && !(SLOT->ssgn ^ (SLOT->ssg & 0x04)))
1421 SLOT->volume = MAX_ATT_INDEX;
1422 }
1423 else /* loop SSG-EG */
1424 {
1425 /* toggle output inversion flag or reset Phase Generator */
1426 if (SLOT->ssg & 0x02)
1427 SLOT->ssgn ^= 4;
1428 else
1429 SLOT->phase = 0;
1430
1431 /* same as Key ON */
1432 if (SLOT->state != EG_ATT)
1433 {
1434 if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/)
1435 {
1436 SLOT->state = (SLOT->volume <= MIN_ATT_INDEX) ? ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC) : EG_ATT;
1437 }
1438 else
1439 {
1440 /* Attack Rate is maximal: directly switch to Decay or Substain */
1441 SLOT->volume = MIN_ATT_INDEX;
1442 SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
1443 }
1444 }
1445 }
1446
1447 /* recalculate EG output */
1448 if (SLOT->ssgn ^ (SLOT->ssg&0x04))
1449 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
1450 else
1451 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1452 }
1453
1454 /* next slot */
1455 SLOT++;
1456 i--;
1457 } while (i);
1458 }
1459
1460
update_phase_lfo_slot(FM_OPN * OPN,FM_SLOT * SLOT,INT32 pms,UINT32 block_fnum)1461 INLINE void update_phase_lfo_slot(FM_OPN *OPN, FM_SLOT *SLOT, INT32 pms, UINT32 block_fnum)
1462 {
1463 UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
1464 INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + pms + OPN->LFO_PM ];
1465
1466 block_fnum = block_fnum*2 + lfo_fn_table_index_offset;
1467
1468 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
1469 {
1470 UINT8 blk = (block_fnum&0x7000) >> 12;
1471 UINT32 fn = block_fnum & 0xfff;
1472
1473 /* recalculate keyscale code */
1474 /*int kc = (blk<<2) | opn_fktable[fn >> 7];*/
1475 /* This really stupid bug caused a read outside of the
1476 array [size 0x10] and returned invalid values.
1477 This caused an annoying vibrato for some notes.
1478 (Note: seems to be a copy-and-paste from OPNWriteReg -> case 0xA0)
1479 Why are MAME cores always SOO buggy ?! */
1480 /* Oh, and before I forget: it's correct in fm.c */
1481 int kc = (blk<<2) | opn_fktable[fn >> 8];
1482 /* Thanks to Blargg - his patch that helped me to find this bug */
1483
1484 /* recalculate (frequency) phase increment counter */
1485 int fc = (OPN->fn_table[fn]>>(7-blk)) + SLOT->DT[kc];
1486
1487 /* (frequency) phase overflow (credits to Nemesis) */
1488 if (fc < 0) fc += OPN->fn_max;
1489
1490 /* update phase */
1491 SLOT->phase += (fc * SLOT->mul) >> 1;
1492 }
1493 else /* LFO phase modulation = zero */
1494 {
1495 SLOT->phase += SLOT->Incr;
1496 }
1497 }
1498
update_phase_lfo_channel(FM_OPN * OPN,FM_CH * CH)1499 INLINE void update_phase_lfo_channel(FM_OPN *OPN, FM_CH *CH)
1500 {
1501 UINT32 block_fnum = CH->block_fnum;
1502
1503 UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
1504 INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + OPN->LFO_PM ];
1505
1506 block_fnum = block_fnum*2 + lfo_fn_table_index_offset;
1507
1508 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
1509 {
1510 UINT8 blk = (block_fnum&0x7000) >> 12;
1511 UINT32 fn = block_fnum & 0xfff;
1512
1513 /* recalculate keyscale code */
1514 /*int kc = (blk<<2) | opn_fktable[fn >> 7];*/
1515 /* the same stupid bug as above */
1516 int kc = (blk<<2) | opn_fktable[fn >> 8];
1517
1518 /* recalculate (frequency) phase increment counter */
1519 int fc = (OPN->fn_table[fn]>>(7-blk));
1520
1521 /* (frequency) phase overflow (credits to Nemesis) */
1522 int finc = fc + CH->SLOT[SLOT1].DT[kc];
1523 if (finc < 0) finc += OPN->fn_max;
1524 CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1;
1525
1526 finc = fc + CH->SLOT[SLOT2].DT[kc];
1527 if (finc < 0) finc += OPN->fn_max;
1528 CH->SLOT[SLOT2].phase += (finc*CH->SLOT[SLOT2].mul) >> 1;
1529
1530 finc = fc + CH->SLOT[SLOT3].DT[kc];
1531 if (finc < 0) finc += OPN->fn_max;
1532 CH->SLOT[SLOT3].phase += (finc*CH->SLOT[SLOT3].mul) >> 1;
1533
1534 finc = fc + CH->SLOT[SLOT4].DT[kc];
1535 if (finc < 0) finc += OPN->fn_max;
1536 CH->SLOT[SLOT4].phase += (finc*CH->SLOT[SLOT4].mul) >> 1;
1537 }
1538 else /* LFO phase modulation = zero */
1539 {
1540 CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
1541 CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
1542 CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
1543 CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
1544 }
1545 }
1546
1547 /* update phase increment and envelope generator */
refresh_fc_eg_slot(FM_OPN * OPN,FM_SLOT * SLOT,int fc,int kc)1548 INLINE void refresh_fc_eg_slot(FM_OPN *OPN, FM_SLOT *SLOT , int fc , int kc )
1549 {
1550 int ksr = kc >> SLOT->KSR;
1551
1552 fc += SLOT->DT[kc];
1553
1554 /* detects frequency overflow (credits to Nemesis) */
1555 if (fc < 0) fc += OPN->fn_max;
1556
1557 /* (frequency) phase increment counter */
1558 SLOT->Incr = (fc * SLOT->mul) >> 1;
1559
1560 if( SLOT->ksr != ksr )
1561 {
1562 SLOT->ksr = ksr;
1563
1564 /* calculate envelope generator rates */
1565 if ((SLOT->ar + SLOT->ksr) < 32+62)
1566 {
1567 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1568 SLOT->eg_sel_ar = eg_rate_select2612[SLOT->ar + SLOT->ksr ];
1569 }
1570 else
1571 {
1572 SLOT->eg_sh_ar = 0;
1573 SLOT->eg_sel_ar = 18*RATE_STEPS; /* verified by Nemesis on real hardware (Attack phase is blocked) */
1574 }
1575
1576 SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
1577 SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
1578 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
1579
1580 SLOT->eg_sel_d1r= eg_rate_select2612[SLOT->d1r + SLOT->ksr];
1581 SLOT->eg_sel_d2r= eg_rate_select2612[SLOT->d2r + SLOT->ksr];
1582 SLOT->eg_sel_rr = eg_rate_select2612[SLOT->rr + SLOT->ksr];
1583 }
1584 }
1585
1586 /* update phase increment counters */
refresh_fc_eg_chan(FM_OPN * OPN,FM_CH * CH)1587 INLINE void refresh_fc_eg_chan(FM_OPN *OPN, FM_CH *CH )
1588 {
1589 if( CH->SLOT[SLOT1].Incr==-1)
1590 {
1591 int fc = CH->fc;
1592 int kc = CH->kcode;
1593 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT1] , fc , kc );
1594 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT2] , fc , kc );
1595 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT3] , fc , kc );
1596 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT4] , fc , kc );
1597 }
1598 }
1599
1600 #define volume_calc(OP) ((OP)->vol_out + (AM & (OP)->AMmask))
1601
op_calc(UINT32 phase,unsigned int env,signed int pm)1602 INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm)
1603 {
1604 UINT32 p;
1605
1606 p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + (pm<<15))) >> FREQ_SH ) & SIN_MASK ];
1607
1608 if (p >= TL_TAB_LEN)
1609 return 0;
1610 return tl_tab[p];
1611 }
1612
op_calc1(UINT32 phase,unsigned int env,signed int pm)1613 INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm)
1614 {
1615 UINT32 p;
1616
1617 p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK ];
1618
1619 if (p >= TL_TAB_LEN)
1620 return 0;
1621 return tl_tab[p];
1622 }
1623
chan_calc(YM2612 * F2612,FM_OPN * OPN,FM_CH * CH)1624 INLINE void chan_calc(YM2612 *F2612, FM_OPN *OPN, FM_CH *CH)
1625 {
1626 UINT32 AM = OPN->LFO_AM >> CH->ams;
1627 unsigned int eg_out;
1628
1629 if (CH->Muted)
1630 return;
1631
1632 OPN->m2 = OPN->c1 = OPN->c2 = OPN->mem = 0;
1633
1634 *CH->mem_connect = CH->mem_value; /* restore delayed sample (MEM) value to m2 or c2 */
1635
1636 eg_out = volume_calc(&CH->SLOT[SLOT1]);
1637 {
1638 INT32 out = CH->op1_out[0] + CH->op1_out[1];
1639 CH->op1_out[0] = CH->op1_out[1];
1640
1641 if( !CH->connect1 )
1642 {
1643 /* algorithm 5 */
1644 OPN->mem = OPN->c1 = OPN->c2 = CH->op1_out[0];
1645 }
1646 else
1647 {
1648 /* other algorithms */
1649 *CH->connect1 += CH->op1_out[0];
1650 }
1651
1652
1653 CH->op1_out[1] = 0;
1654 if( eg_out < ENV_QUIET ) /* SLOT 1 */
1655 {
1656 if (!CH->FB)
1657 out=0;
1658
1659 CH->op1_out[1] = op_calc1(CH->SLOT[SLOT1].phase, eg_out, (out<<CH->FB) );
1660 }
1661 }
1662
1663 eg_out = volume_calc(&CH->SLOT[SLOT3]);
1664 if( eg_out < ENV_QUIET ) /* SLOT 3 */
1665 *CH->connect3 += op_calc(CH->SLOT[SLOT3].phase, eg_out, OPN->m2);
1666
1667 eg_out = volume_calc(&CH->SLOT[SLOT2]);
1668 if( eg_out < ENV_QUIET ) /* SLOT 2 */
1669 *CH->connect2 += op_calc(CH->SLOT[SLOT2].phase, eg_out, OPN->c1);
1670
1671 eg_out = volume_calc(&CH->SLOT[SLOT4]);
1672 if( eg_out < ENV_QUIET ) /* SLOT 4 */
1673 *CH->connect4 += op_calc(CH->SLOT[SLOT4].phase, eg_out, OPN->c2);
1674
1675
1676 /* store current MEM */
1677 CH->mem_value = OPN->mem;
1678
1679 /* update phase counters AFTER output calculations */
1680 if(CH->pms)
1681 {
1682 /* add support for 3 slot mode */
1683 if ((OPN->ST.mode & 0xC0) && (CH == &F2612->CH[2]))
1684 {
1685 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT1], CH->pms, OPN->SL3.block_fnum[1]);
1686 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT2], CH->pms, OPN->SL3.block_fnum[2]);
1687 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT3], CH->pms, OPN->SL3.block_fnum[0]);
1688 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT4], CH->pms, CH->block_fnum);
1689 }
1690 else update_phase_lfo_channel(OPN, CH);
1691 }
1692 else /* no LFO phase modulation */
1693 {
1694 CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
1695 CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
1696 CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
1697 CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
1698 }
1699 }
1700
FMCloseTable(void)1701 static void FMCloseTable( void )
1702 {
1703 #ifdef SAVE_SAMPLE
1704 fclose(sample[0]);
1705 #endif
1706 return;
1707 }
1708
1709
1710 /* CSM Key Controll */
CSMKeyControll(FM_OPN * OPN,FM_CH * CH)1711 INLINE void CSMKeyControll(FM_OPN *OPN, FM_CH *CH)
1712 {
1713 /* all key ON (verified by Nemesis on real hardware) */
1714 FM_KEYON_CSM(OPN,CH,SLOT1);
1715 FM_KEYON_CSM(OPN,CH,SLOT2);
1716 FM_KEYON_CSM(OPN,CH,SLOT3);
1717 FM_KEYON_CSM(OPN,CH,SLOT4);
1718 OPN->SL3.key_csm = 1;
1719 }
1720
1721 #ifdef __STATE_H__
1722 /* FM channel save , internal state only */
FMsave_state_channel(running_device * device,FM_CH * CH,int num_ch)1723 static void FMsave_state_channel(running_device *device,FM_CH *CH,int num_ch)
1724 {
1725 int slot , ch;
1726
1727 for(ch=0;ch<num_ch;ch++,CH++)
1728 {
1729 /* channel */
1730 state_save_register_device_item_array(device, ch, CH->op1_out);
1731 state_save_register_device_item(device, ch, CH->fc);
1732 /* slots */
1733 for(slot=0;slot<4;slot++)
1734 {
1735 FM_SLOT *SLOT = &CH->SLOT[slot];
1736 state_save_register_device_item(device, ch * 4 + slot, SLOT->phase);
1737 state_save_register_device_item(device, ch * 4 + slot, SLOT->state);
1738 state_save_register_device_item(device, ch * 4 + slot, SLOT->volume);
1739 }
1740 }
1741 }
1742
FMsave_state_st(running_device * device,FM_ST * ST)1743 static void FMsave_state_st(running_device *device,FM_ST *ST)
1744 {
1745 #if FM_BUSY_FLAG_SUPPORT
1746 state_save_register_device_item(device, 0, ST->busy_expiry_time.seconds );
1747 state_save_register_device_item(device, 0, ST->busy_expiry_time.attoseconds );
1748 #endif
1749 state_save_register_device_item(device, 0, ST->address );
1750 state_save_register_device_item(device, 0, ST->irq );
1751 state_save_register_device_item(device, 0, ST->irqmask );
1752 state_save_register_device_item(device, 0, ST->status );
1753 state_save_register_device_item(device, 0, ST->mode );
1754 state_save_register_device_item(device, 0, ST->prescaler_sel );
1755 state_save_register_device_item(device, 0, ST->fn_h );
1756 state_save_register_device_item(device, 0, ST->TA );
1757 state_save_register_device_item(device, 0, ST->TAC );
1758 state_save_register_device_item(device, 0, ST->TB );
1759 state_save_register_device_item(device, 0, ST->TBC );
1760 }
1761 #endif /* _STATE_H */
1762
1763 #if BUILD_OPN
1764 /* write a OPN mode register 0x20-0x2f */
OPNWriteMode(FM_OPN * OPN,int r,int v)1765 static void OPNWriteMode(FM_OPN *OPN, int r, int v)
1766 {
1767 UINT8 c;
1768 FM_CH *CH;
1769
1770 switch(r)
1771 {
1772 case 0x21: /* Test */
1773 break;
1774 case 0x22: /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */
1775 if (v&8) /* LFO enabled ? */
1776 {
1777 /*if (!OPN->lfo_timer_overflow)
1778 {
1779 // restart LFO
1780 OPN->lfo_cnt = 0;
1781 OPN->lfo_timer = 0;
1782 OPN->LFO_AM = 0;
1783 OPN->LFO_PM = 0;
1784 }*/
1785
1786 OPN->lfo_timer_overflow = lfo_samples_per_step[v&7] << LFO_SH;
1787 }
1788 else
1789 {
1790 // Valley Bell: Ported from Genesis Plus GX 1.71
1791 // hold LFO waveform in reset state
1792 OPN->lfo_timer_overflow = 0;
1793 OPN->lfo_timer = 0;
1794 OPN->lfo_cnt = 0;
1795
1796
1797 OPN->LFO_PM = 0;
1798 OPN->LFO_AM = 126;
1799 //OPN->lfo_timer_overflow = 0;
1800 }
1801 break;
1802 case 0x24: /* timer A High 8*/
1803 OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
1804 break;
1805 case 0x25: /* timer A Low 2*/
1806 OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
1807 break;
1808 case 0x26: /* timer B */
1809 OPN->ST.TB = v;
1810 break;
1811 case 0x27: /* mode, timer control */
1812 set_timers( OPN, &(OPN->ST),OPN->ST.param,v );
1813 break;
1814 case 0x28: /* key on / off */
1815 c = v & 0x03;
1816 if( c == 3 ) break;
1817 if( (v&0x04) && (OPN->type & TYPE_6CH) ) c+=3;
1818 CH = OPN->P_CH;
1819 CH = &CH[c];
1820 if(v&0x10) FM_KEYON(OPN,CH,SLOT1); else FM_KEYOFF(OPN,CH,SLOT1);
1821 if(v&0x20) FM_KEYON(OPN,CH,SLOT2); else FM_KEYOFF(OPN,CH,SLOT2);
1822 if(v&0x40) FM_KEYON(OPN,CH,SLOT3); else FM_KEYOFF(OPN,CH,SLOT3);
1823 if(v&0x80) FM_KEYON(OPN,CH,SLOT4); else FM_KEYOFF(OPN,CH,SLOT4);
1824 break;
1825 }
1826 }
1827
1828 /* write a OPN register (0x30-0xff) */
OPNWriteReg(FM_OPN * OPN,int r,int v)1829 static void OPNWriteReg(FM_OPN *OPN, int r, int v)
1830 {
1831 FM_CH *CH;
1832 FM_SLOT *SLOT;
1833
1834 UINT8 c = OPN_CHAN(r);
1835
1836 if (c == 3) return; /* 0xX3,0xX7,0xXB,0xXF */
1837
1838 if (r >= 0x100) c+=3;
1839
1840 CH = OPN->P_CH;
1841 CH = &CH[c];
1842
1843 SLOT = &(CH->SLOT[OPN_SLOT(r)]);
1844
1845 switch( r & 0xf0 ) {
1846 case 0x30: /* DET , MUL */
1847 set_det_mul(&OPN->ST,CH,SLOT,v);
1848 break;
1849
1850 case 0x40: /* TL */
1851 set_tl(CH,SLOT,v);
1852 break;
1853
1854 case 0x50: /* KS, AR */
1855 set_ar_ksr(OPN->type,CH,SLOT,v);
1856 break;
1857
1858 case 0x60: /* bit7 = AM ENABLE, DR */
1859 set_dr(OPN->type, SLOT,v);
1860
1861 if(OPN->type & TYPE_LFOPAN) /* YM2608/2610/2610B/2612 */
1862 {
1863 SLOT->AMmask = (v&0x80) ? ~0 : 0;
1864 }
1865 break;
1866
1867 case 0x70: /* SR */
1868 set_sr(OPN->type,SLOT,v);
1869 break;
1870
1871 case 0x80: /* SL, RR */
1872 set_sl_rr(OPN->type,SLOT,v);
1873 break;
1874
1875 case 0x90: /* SSG-EG */
1876 SLOT->ssg = v&0x0f;
1877
1878 /* recalculate EG output */
1879 if (SLOT->state > EG_REL)
1880 {
1881 if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)))
1882 SLOT->vol_out = ((UINT32)(0x200 - SLOT->volume) & MAX_ATT_INDEX) + SLOT->tl;
1883 else
1884 SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
1885 }
1886
1887 /* SSG-EG envelope shapes :
1888
1889 E AtAlH
1890 1 0 0 0 \\\\
1891
1892 1 0 0 1 \___
1893
1894 1 0 1 0 \/\/
1895 ___
1896 1 0 1 1 \
1897
1898 1 1 0 0 ////
1899 ___
1900 1 1 0 1 /
1901
1902 1 1 1 0 /\/\
1903
1904 1 1 1 1 /___
1905
1906
1907 E = SSG-EG enable
1908
1909
1910 The shapes are generated using Attack, Decay and Sustain phases.
1911
1912 Each single character in the diagrams above represents this whole
1913 sequence:
1914
1915 - when KEY-ON = 1, normal Attack phase is generated (*without* any
1916 difference when compared to normal mode),
1917
1918 - later, when envelope level reaches minimum level (max volume),
1919 the EG switches to Decay phase (which works with bigger steps
1920 when compared to normal mode - see below),
1921
1922 - later when envelope level passes the SL level,
1923 the EG swithes to Sustain phase (which works with bigger steps
1924 when compared to normal mode - see below),
1925
1926 - finally when envelope level reaches maximum level (min volume),
1927 the EG switches to Attack phase again (depends on actual waveform).
1928
1929 Important is that when switch to Attack phase occurs, the phase counter
1930 of that operator will be zeroed-out (as in normal KEY-ON) but not always.
1931 (I havent found the rule for that - perhaps only when the output level is low)
1932
1933 The difference (when compared to normal Envelope Generator mode) is
1934 that the resolution in Decay and Sustain phases is 4 times lower;
1935 this results in only 256 steps instead of normal 1024.
1936 In other words:
1937 when SSG-EG is disabled, the step inside of the EG is one,
1938 when SSG-EG is enabled, the step is four (in Decay and Sustain phases).
1939
1940 Times between the level changes are the same in both modes.
1941
1942
1943 Important:
1944 Decay 1 Level (so called SL) is compared to actual SSG-EG output, so
1945 it is the same in both SSG and no-SSG modes, with this exception:
1946
1947 when the SSG-EG is enabled and is generating raising levels
1948 (when the EG output is inverted) the SL will be found at wrong level !!!
1949 For example, when SL=02:
1950 0 -6 = -6dB in non-inverted EG output
1951 96-6 = -90dB in inverted EG output
1952 Which means that EG compares its level to SL as usual, and that the
1953 output is simply inverted afterall.
1954
1955
1956 The Yamaha's manuals say that AR should be set to 0x1f (max speed).
1957 That is not necessary, but then EG will be generating Attack phase.
1958
1959 */
1960
1961
1962 break;
1963
1964 case 0xa0:
1965 switch( OPN_SLOT(r) )
1966 {
1967 case 0: /* 0xa0-0xa2 : FNUM1 */
1968 {
1969 UINT32 fn = (((UINT32)( (OPN->ST.fn_h)&7))<<8) + v;
1970 UINT8 blk = OPN->ST.fn_h>>3;
1971 /* keyscale code */
1972 CH->kcode = (blk<<2) | opn_fktable[fn >> 7];
1973 /* phase increment counter */
1974 CH->fc = OPN->fn_table[fn*2]>>(7-blk);
1975
1976 /* store fnum in clear form for LFO PM calculations */
1977 CH->block_fnum = (blk<<11) | fn;
1978
1979 CH->SLOT[SLOT1].Incr=-1;
1980 }
1981 break;
1982 case 1: /* 0xa4-0xa6 : FNUM2,BLK */
1983 OPN->ST.fn_h = v&0x3f;
1984 break;
1985 case 2: /* 0xa8-0xaa : 3CH FNUM1 */
1986 if(r < 0x100)
1987 {
1988 UINT32 fn = (((UINT32)(OPN->SL3.fn_h&7))<<8) + v;
1989 UINT8 blk = OPN->SL3.fn_h>>3;
1990 /* keyscale code */
1991 OPN->SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];
1992 /* phase increment counter */
1993 OPN->SL3.fc[c] = OPN->fn_table[fn*2]>>(7-blk);
1994 OPN->SL3.block_fnum[c] = (blk<<11) | fn;
1995 (OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
1996 }
1997 break;
1998 case 3: /* 0xac-0xae : 3CH FNUM2,BLK */
1999 if(r < 0x100)
2000 OPN->SL3.fn_h = v&0x3f;
2001 break;
2002 }
2003 break;
2004
2005 case 0xb0:
2006 switch( OPN_SLOT(r) )
2007 {
2008 case 0: /* 0xb0-0xb2 : FB,ALGO */
2009 {
2010 int feedback = (v>>3)&7;
2011 CH->ALGO = v&7;
2012 CH->FB = feedback ? feedback+6 : 0;
2013 setup_connection( OPN, CH, c );
2014 }
2015 break;
2016 case 1: /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */
2017 if( OPN->type & TYPE_LFOPAN)
2018 {
2019 /* b0-2 PMS */
2020 CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */
2021
2022 /* b4-5 AMS */
2023 CH->ams = lfo_ams_depth_shift[(v>>4) & 0x03];
2024
2025 /* PAN : b7 = L, b6 = R */
2026 OPN->pan[ c*2 ] = (v & 0x80) ? ~0 : 0;
2027 OPN->pan[ c*2+1 ] = (v & 0x40) ? ~0 : 0;
2028
2029 }
2030 break;
2031 }
2032 break;
2033 }
2034 }
2035
2036 /* initialize time tables */
init_timetables(FM_OPN * OPN,double freqbase)2037 static void init_timetables(FM_OPN *OPN, double freqbase)
2038 {
2039 int i,d;
2040 double rate;
2041
2042 /* DeTune table */
2043 for (d = 0;d <= 3;d++)
2044 {
2045 for (i = 0;i <= 31;i++)
2046 {
2047 rate = ((double)dt_tab[d*32 + i]) * freqbase * (1<<(FREQ_SH-10)); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
2048 OPN->ST.dt_tab[d][i] = (INT32) rate;
2049 OPN->ST.dt_tab[d+4][i] = -OPN->ST.dt_tab[d][i];
2050 }
2051 }
2052
2053 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
2054 but LFO works with one more bit of a precision so we really need 4096 elements */
2055 /* calculate fnumber -> increment counter table */
2056 for(i = 0; i < 4096; i++)
2057 {
2058 /* freq table for octave 7 */
2059 /* OPN phase increment counter = 20bit */
2060 /* the correct formula is : F-Number = (144 * fnote * 2^20 / M) / 2^(B-1) */
2061 /* where sample clock is M/144 */
2062 /* this means the increment value for one clock sample is FNUM * 2^(B-1) = FNUM * 64 for octave 7 */
2063 /* we also need to handle the ratio between the chip frequency and the emulated frequency (can be 1.0) */
2064 OPN->fn_table[i] = (UINT32)( (double)i * 32 * freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
2065 }
2066
2067 /* maximal frequency is required for Phase overflow calculation, register size is 17 bits (Nemesis) */
2068 OPN->fn_max = (UINT32)( (double)0x20000 * freqbase * (1<<(FREQ_SH-10)) );
2069 }
2070
2071 /* prescaler set (and make time tables) */
OPNSetPres(FM_OPN * OPN,int pres,int timer_prescaler,int SSGpres)2072 static void OPNSetPres(FM_OPN *OPN, int pres, int timer_prescaler, int SSGpres)
2073 {
2074 /* frequency base */
2075 OPN->ST.freqbase = (OPN->ST.rate) ? ((double)OPN->ST.clock / OPN->ST.rate) / pres : 0;
2076
2077 /* EG is updated every 3 samples */
2078 OPN->eg_timer_add = (UINT32)((1<<EG_SH) * OPN->ST.freqbase);
2079 OPN->eg_timer_overflow = ( 3 ) * (1<<EG_SH);
2080
2081 /* LFO timer increment (every samples) */
2082 OPN->lfo_timer_add = (UINT32)((1<<LFO_SH) * OPN->ST.freqbase);
2083
2084 /* Timer base time */
2085 OPN->ST.timer_prescaler = timer_prescaler;
2086
2087 /* SSG part prescaler set */
2088 if( SSGpres ) (*OPN->ST.SSG->set_clock)( OPN->ST.param, OPN->ST.clock * 2 / SSGpres );
2089
2090 /* make time tables */
2091 init_timetables(OPN, OPN->ST.freqbase);
2092 }
2093
reset_channels(FM_ST * ST,FM_CH * CH,int num)2094 static void reset_channels( FM_ST *ST , FM_CH *CH , int num )
2095 {
2096 int c,s;
2097
2098 for( c = 0 ; c < num ; c++ )
2099 {
2100 //memset(&CH[c], 0x00, sizeof(FM_CH));
2101 CH[c].mem_value = 0;
2102 CH[c].op1_out[0] = 0;
2103 CH[c].op1_out[1] = 0;
2104 CH[c].fc = 0;
2105 for(s = 0 ; s < 4 ; s++ )
2106 {
2107 //memset(&CH[c].SLOT[s], 0x00, sizeof(FM_SLOT));
2108 CH[c].SLOT[s].Incr = -1;
2109 CH[c].SLOT[s].key = 0;
2110 CH[c].SLOT[s].phase = 0;
2111 CH[c].SLOT[s].ssg = 0;
2112 CH[c].SLOT[s].ssgn = 0;
2113 CH[c].SLOT[s].state= EG_OFF;
2114 CH[c].SLOT[s].volume = MAX_ATT_INDEX;
2115 CH[c].SLOT[s].vol_out= MAX_ATT_INDEX;
2116 }
2117 }
2118 }
2119
2120 /* initialize generic tables */
init_tables(void)2121 static void init_tables(void)
2122 {
2123 signed int i,x;
2124 signed int n;
2125 double o,m;
2126
2127 /* build Linear Power Table */
2128 for (x=0; x<TL_RES_LEN; x++)
2129 {
2130 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);
2131 m = floor(m);
2132
2133 /* we never reach (1<<16) here due to the (x+1) */
2134 /* result fits within 16 bits at maximum */
2135
2136 n = (int)m; /* 16 bits here */
2137 n >>= 4; /* 12 bits here */
2138 if (n&1) /* round to nearest */
2139 n = (n>>1)+1;
2140 else
2141 n = n>>1;
2142 /* 11 bits here (rounded) */
2143 n <<= 2; /* 13 bits here (as in real chip) */
2144
2145
2146 /* 14 bits (with sign bit) */
2147 tl_tab[ x*2 + 0 ] = n;
2148 tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ];
2149
2150 /* one entry in the 'Power' table use the following format, xxxxxyyyyyyyys with: */
2151 /* s = sign bit */
2152 /* yyyyyyyy = 8-bits decimal part (0-TL_RES_LEN) */
2153 /* xxxxx = 5-bits integer 'shift' value (0-31) but, since Power table output is 13 bits, */
2154 /* any value above 13 (included) would be discarded. */
2155 for (i=1; i<13; i++)
2156 {
2157 tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i;
2158 tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ];
2159 }
2160 }
2161
2162 /* build Logarithmic Sinus table */
2163 for (i=0; i<SIN_LEN; i++)
2164 {
2165 /* non-standard sinus */
2166 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */
2167 /* we never reach zero here due to ((i*2)+1) */
2168
2169 if (m>0.0)
2170 o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */
2171 else
2172 o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */
2173
2174 o = o / (ENV_STEP/4);
2175
2176 n = (int)(2.0*o);
2177 if (n&1) /* round to nearest */
2178 n = (n>>1)+1;
2179 else
2180 n = n>>1;
2181
2182 /* 13-bits (8.5) value is formatted for above 'Power' table */
2183 sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
2184 }
2185
2186 /* build LFO PM modulation table */
2187 for(i = 0; i < 8; i++) /* 8 PM depths */
2188 {
2189 UINT8 fnum;
2190 for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */
2191 {
2192 UINT8 value;
2193 UINT8 step;
2194 UINT32 offset_depth = i;
2195 UINT32 offset_fnum_bit;
2196 UINT32 bit_tmp;
2197
2198 for (step=0; step<8; step++)
2199 {
2200 value = 0;
2201 for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */
2202 {
2203 if (fnum & (1<<bit_tmp)) /* only if bit "bit_tmp" is set */
2204 {
2205 offset_fnum_bit = bit_tmp * 8;
2206 value += lfo_pm_output[offset_fnum_bit + offset_depth][step];
2207 }
2208 }
2209 /* 32 steps for LFO PM (sinus) */
2210 lfo_pm_table[(fnum*32*8) + (i*32) + step + 0] = value;
2211 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+ 8] = value;
2212 lfo_pm_table[(fnum*32*8) + (i*32) + step +16] = -value;
2213 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+24] = -value;
2214 }
2215
2216 }
2217 }
2218
2219 #ifdef SAVE_SAMPLE
2220 sample[0]=fopen("sampsum.pcm","wb");
2221 #endif
2222 }
2223
2224 #endif /* BUILD_OPN */
2225
2226 #if (BUILD_YM2612||BUILD_YM3438)
2227 /*******************************************************************************/
2228 /* YM2612 local section */
2229 /*******************************************************************************/
2230
2231 /* Generate samples for one of the YM2612s */
ym2612_update_one(void * chip,FMSAMPLE ** buffer,int length)2232 void ym2612_update_one(void *chip, FMSAMPLE **buffer, int length)
2233 {
2234 YM2612 *F2612 = (YM2612 *)chip;
2235 FM_OPN *OPN = &F2612->OPN;
2236 INT32 *out_fm = OPN->out_fm;
2237 int i;
2238 FMSAMPLE *bufL,*bufR;
2239 INT32 dacout;
2240 FM_CH *cch[6];
2241 int lt,rt;
2242
2243 /* set bufer */
2244 bufL = buffer[0];
2245 bufR = buffer[1];
2246
2247 cch[0] = &F2612->CH[0];
2248 cch[1] = &F2612->CH[1];
2249 cch[2] = &F2612->CH[2];
2250 cch[3] = &F2612->CH[3];
2251 cch[4] = &F2612->CH[4];
2252 cch[5] = &F2612->CH[5];
2253
2254 if (! F2612->MuteDAC)
2255 dacout = F2612->dacout;
2256 else
2257 dacout = 0;
2258
2259 /* refresh PG and EG */
2260 refresh_fc_eg_chan( OPN, cch[0] );
2261 refresh_fc_eg_chan( OPN, cch[1] );
2262 if( (OPN->ST.mode & 0xc0) )
2263 {
2264 /* 3SLOT MODE */
2265 if( cch[2]->SLOT[SLOT1].Incr==-1)
2266 {
2267 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2268 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2269 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2270 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2271 }
2272 }else refresh_fc_eg_chan( OPN, cch[2] );
2273 refresh_fc_eg_chan( OPN, cch[3] );
2274 refresh_fc_eg_chan( OPN, cch[4] );
2275 refresh_fc_eg_chan( OPN, cch[5] );
2276 if (! length)
2277 {
2278 update_ssg_eg_channel(&cch[0]->SLOT[SLOT1]);
2279 update_ssg_eg_channel(&cch[1]->SLOT[SLOT1]);
2280 update_ssg_eg_channel(&cch[2]->SLOT[SLOT1]);
2281 update_ssg_eg_channel(&cch[3]->SLOT[SLOT1]);
2282 update_ssg_eg_channel(&cch[4]->SLOT[SLOT1]);
2283 update_ssg_eg_channel(&cch[5]->SLOT[SLOT1]);
2284 }
2285
2286
2287 /* buffering */
2288 for(i=0; i < length ; i++)
2289 {
2290 /* clear outputs */
2291 out_fm[0] = 0;
2292 out_fm[1] = 0;
2293 out_fm[2] = 0;
2294 out_fm[3] = 0;
2295 out_fm[4] = 0;
2296 out_fm[5] = 0;
2297
2298 /* update SSG-EG output */
2299 update_ssg_eg_channel(&cch[0]->SLOT[SLOT1]);
2300 update_ssg_eg_channel(&cch[1]->SLOT[SLOT1]);
2301 update_ssg_eg_channel(&cch[2]->SLOT[SLOT1]);
2302 update_ssg_eg_channel(&cch[3]->SLOT[SLOT1]);
2303 update_ssg_eg_channel(&cch[4]->SLOT[SLOT1]);
2304 update_ssg_eg_channel(&cch[5]->SLOT[SLOT1]);
2305
2306 /* calculate FM */
2307 if (! F2612->dac_test)
2308 {
2309 chan_calc(F2612, OPN, cch[0]);
2310 chan_calc(F2612, OPN, cch[1]);
2311 chan_calc(F2612, OPN, cch[2]);
2312 chan_calc(F2612, OPN, cch[3]);
2313 chan_calc(F2612, OPN, cch[4]);
2314 if( F2612->dacen )
2315 *cch[5]->connect4 += dacout;
2316 else
2317 chan_calc(F2612, OPN, cch[5]);
2318 }
2319 else
2320 {
2321 out_fm[0] = out_fm[1] = dacout;
2322 out_fm[2] = out_fm[3] = dacout;
2323 out_fm[5] = dacout;
2324 }
2325
2326 /* advance LFO */
2327 advance_lfo(OPN);
2328
2329 /* advance envelope generator */
2330 OPN->eg_timer += OPN->eg_timer_add;
2331 while (OPN->eg_timer >= OPN->eg_timer_overflow)
2332 {
2333 OPN->eg_timer -= OPN->eg_timer_overflow;
2334 OPN->eg_cnt++;
2335
2336 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
2337 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
2338 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
2339 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
2340 advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]);
2341 advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]);
2342 }
2343
2344 /*fprintf(hFile, "%u", FileSample, out_fm[0]);
2345 for (lt = 0; lt < 6; lt ++)
2346 fprintf(hFile, "\t%d", out_fm[lt]);
2347 fprintf(hFile, "\n");
2348 FileSample ++;*/
2349
2350 if (out_fm[0] > 8192) out_fm[0] = 8192;
2351 else if (out_fm[0] < -8192) out_fm[0] = -8192;
2352 if (out_fm[1] > 8192) out_fm[1] = 8192;
2353 else if (out_fm[1] < -8192) out_fm[1] = -8192;
2354 if (out_fm[2] > 8192) out_fm[2] = 8192;
2355 else if (out_fm[2] < -8192) out_fm[2] = -8192;
2356 if (out_fm[3] > 8192) out_fm[3] = 8192;
2357 else if (out_fm[3] < -8192) out_fm[3] = -8192;
2358 if (out_fm[4] > 8192) out_fm[4] = 8192;
2359 else if (out_fm[4] < -8192) out_fm[4] = -8192;
2360 if (out_fm[5] > 8192) out_fm[5] = 8192;
2361 else if (out_fm[5] < -8192) out_fm[5] = -8192;
2362
2363 /* 6-channels mixing */
2364 lt = ((out_fm[0]>>0) & OPN->pan[0]);
2365 rt = ((out_fm[0]>>0) & OPN->pan[1]);
2366 lt += ((out_fm[1]>>0) & OPN->pan[2]);
2367 rt += ((out_fm[1]>>0) & OPN->pan[3]);
2368 lt += ((out_fm[2]>>0) & OPN->pan[4]);
2369 rt += ((out_fm[2]>>0) & OPN->pan[5]);
2370 lt += ((out_fm[3]>>0) & OPN->pan[6]);
2371 rt += ((out_fm[3]>>0) & OPN->pan[7]);
2372 if (! F2612->dac_test)
2373 {
2374 lt += ((out_fm[4]>>0) & OPN->pan[8]);
2375 rt += ((out_fm[4]>>0) & OPN->pan[9]);
2376 }
2377 else
2378 {
2379 lt += dacout;
2380 lt += dacout;
2381 }
2382 lt += ((out_fm[5]>>0) & OPN->pan[10]);
2383 rt += ((out_fm[5]>>0) & OPN->pan[11]);
2384
2385 // Limit( lt, MAXOUT, MINOUT );
2386 // Limit( rt, MAXOUT, MINOUT );
2387
2388 #ifdef SAVE_SAMPLE
2389 SAVE_ALL_CHANNELS
2390 #endif
2391
2392 /* buffering */
2393 if (F2612->WaveOutMode & 0x01)
2394 F2612->WaveL = lt;
2395 if (F2612->WaveOutMode & 0x02)
2396 F2612->WaveR = rt;
2397 if (F2612->WaveOutMode ^ 0x03)
2398 F2612->WaveOutMode ^= 0x03;
2399 bufL[i] = F2612->WaveL;
2400 bufR[i] = F2612->WaveR;
2401
2402 /* CSM mode: if CSM Key ON has occured, CSM Key OFF need to be sent */
2403 /* only if Timer A does not overflow again (i.e CSM Key ON not set again) */
2404 OPN->SL3.key_csm <<= 1;
2405
2406 /* timer A control */
2407 //INTERNAL_TIMER_A( &OPN->ST , cch[2] )
2408 {
2409 if( OPN->ST.TAC && (OPN->ST.timer_handler==0) )
2410 if( (OPN->ST.TAC -= (int)(OPN->ST.freqbase*4096)) <= 0 )
2411 {
2412 TimerAOver( &OPN->ST );
2413 // CSM mode total level latch and auto key on
2414 if( OPN->ST.mode & 0x80 )
2415 CSMKeyControll( OPN, cch[2] );
2416 }
2417 }
2418
2419 /* CSM Mode Key ON still disabled */
2420 if (OPN->SL3.key_csm & 2)
2421 {
2422 /* CSM Mode Key OFF (verified by Nemesis on real hardware) */
2423 FM_KEYOFF_CSM(cch[2],SLOT1);
2424 FM_KEYOFF_CSM(cch[2],SLOT2);
2425 FM_KEYOFF_CSM(cch[2],SLOT3);
2426 FM_KEYOFF_CSM(cch[2],SLOT4);
2427 OPN->SL3.key_csm = 0;
2428 }
2429 }
2430
2431 /* timer B control */
2432 // INTERNAL_TIMER_B(&OPN->ST,length)
2433 }
2434
2435 #ifdef __STATE_H__
ym2612_postload(void * chip)2436 void ym2612_postload(void *chip)
2437 {
2438 if (chip)
2439 {
2440 YM2612 *F2612 = (YM2612 *)chip;
2441 int r;
2442
2443 /* DAC data & port */
2444 F2612->dacout = ((int)F2612->REGS[0x2a] - 0x80) << 6; /* level unknown */
2445 F2612->dacen = F2612->REGS[0x2d] & 0x80;
2446 /* OPN registers */
2447 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
2448 for(r=0x30;r<0x9e;r++)
2449 if((r&3) != 3)
2450 {
2451 OPNWriteReg(&F2612->OPN,r,F2612->REGS[r]);
2452 OPNWriteReg(&F2612->OPN,r|0x100,F2612->REGS[r|0x100]);
2453 }
2454 /* FB / CONNECT , L / R / AMS / PMS */
2455 for(r=0xb0;r<0xb6;r++)
2456 if((r&3) != 3)
2457 {
2458 OPNWriteReg(&F2612->OPN,r,F2612->REGS[r]);
2459 OPNWriteReg(&F2612->OPN,r|0x100,F2612->REGS[r|0x100]);
2460 }
2461 /* channels */
2462 /*FM_channel_postload(F2612->CH,6);*/
2463 }
2464 }
2465
YM2612_save_state(YM2612 * F2612,running_device * device)2466 static void YM2612_save_state(YM2612 *F2612, running_device *device)
2467 {
2468 state_save_register_device_item_array(device, 0, F2612->REGS);
2469 FMsave_state_st(device,&F2612->OPN.ST);
2470 FMsave_state_channel(device,F2612->CH,6);
2471 /* 3slots */
2472 state_save_register_device_item_array(device, 0, F2612->OPN.SL3.fc);
2473 state_save_register_device_item(device, 0, F2612->OPN.SL3.fn_h);
2474 state_save_register_device_item_array(device, 0, F2612->OPN.SL3.kcode);
2475 /* address register1 */
2476 state_save_register_device_item(device, 0, F2612->addr_A1);
2477 }
2478 #endif /* _STATE_H */
2479
2480 /* initialize YM2612 emulator(s) */
2481 //void * ym2612_init(void *param, running_device *device, int clock, int rate,
2482 // FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler)
ym2612_init(void * param,int clock,int rate,FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler,UINT8 * IsVGMInit,int Flags)2483 void * ym2612_init(void *param, int clock, int rate,
2484 FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler,
2485 UINT8 *IsVGMInit, int Flags)
2486 {
2487 int i;
2488
2489 YM2612 *F2612;
2490
2491 /* allocate extend state space */
2492 //F2612 = auto_alloc_clear(device->machine, YM2612);
2493 F2612 = (YM2612 *)malloc(sizeof(YM2612));
2494 if (F2612 == NULL)
2495 return NULL;
2496 memset(F2612, 0x00, sizeof(YM2612));
2497 /* allocate total level table (128kb space) */
2498 init_tables();
2499
2500 F2612->OPN.ST.param = param;
2501 F2612->OPN.type = TYPE_YM2612;
2502 F2612->OPN.P_CH = F2612->CH;
2503 //F2612->OPN.ST.device = device;
2504 F2612->OPN.ST.clock = clock;
2505 F2612->OPN.ST.rate = rate;
2506 /* F2612->OPN.ST.irq = 0; */
2507 /* F2612->OPN.ST.status = 0; */
2508 /* Extend handler */
2509 F2612->OPN.ST.timer_handler = timer_handler;
2510 F2612->OPN.ST.IRQ_Handler = IRQHandler;
2511
2512 F2612->PseudoSt = (Flags >> 2) & 0x01;
2513
2514 if (F2612->PseudoSt)
2515 F2612->WaveOutMode = 0x01;
2516 else
2517 F2612->WaveOutMode = 0x03;
2518 /*hFile = fopen("YM2612.log", "wt");
2519 fprintf(hFile, "Clock: %d, Sample Rate: %d\n", clock, rate);
2520 fprintf(hFile, "Sample\tCh 0\tCh 1\tCh 2\tCh 3\tCh 4\tCh 5\n");
2521 FileSample = 0;*/
2522
2523 #ifdef __STATE_H__
2524 YM2612_save_state(F2612, device);
2525 #endif
2526 F2612->OPN.IsVGMInit = IsVGMInit;
2527 for (i = 0; i < 6; i++)
2528 F2612->CH[i].IsVGMInit = IsVGMInit;
2529
2530 return F2612;
2531 }
2532
2533 /* shut down emulator */
ym2612_shutdown(void * chip)2534 void ym2612_shutdown(void *chip)
2535 {
2536 YM2612 *F2612 = (YM2612 *)chip;
2537 //fclose(hFile);
2538
2539 FMCloseTable();
2540 //auto_free(F2612->OPN.ST.device->machine, F2612);
2541 free(F2612);
2542 }
2543
2544 /* reset one of chip */
ym2612_reset_chip(void * chip)2545 void ym2612_reset_chip(void *chip)
2546 {
2547 int i;
2548 YM2612 *F2612 = (YM2612 *)chip;
2549 FM_OPN *OPN = &F2612->OPN;
2550
2551 OPNSetPres( OPN, 6*24, 6*24, 0);
2552 /* status clear */
2553 FM_IRQMASK_SET(&OPN->ST,0x03);
2554 FM_BUSY_CLEAR(&OPN->ST);
2555 //OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2556
2557 OPN->eg_timer = 0;
2558 OPN->eg_cnt = 0;
2559
2560 OPN->lfo_timer = 0;
2561 OPN->lfo_cnt = 0;
2562 OPN->LFO_AM = 126;
2563 OPN->LFO_PM = 0;
2564
2565 OPN->ST.TAC = 0;
2566 OPN->ST.TBC = 0;
2567
2568 OPN->SL3.key_csm = 0;
2569
2570 OPN->ST.status = 0;
2571 OPN->ST.mode = 0;
2572
2573 memset(F2612->REGS, 0x00, sizeof(UINT8) * 512);
2574
2575 OPNWriteMode(OPN,0x22,0x00);
2576
2577 OPNWriteMode(OPN,0x27,0x30);
2578 OPNWriteMode(OPN,0x26,0x00);
2579 OPNWriteMode(OPN,0x25,0x00);
2580 OPNWriteMode(OPN,0x24,0x00);
2581
2582 reset_channels( &OPN->ST , &F2612->CH[0] , 6 );
2583
2584 for(i = 0xb6 ; i >= 0xb4 ; i-- )
2585 {
2586 OPNWriteReg(OPN,i ,0xc0);
2587 OPNWriteReg(OPN,i|0x100,0xc0);
2588 }
2589 for(i = 0xb2 ; i >= 0x30 ; i-- )
2590 {
2591 OPNWriteReg(OPN,i ,0);
2592 OPNWriteReg(OPN,i|0x100,0);
2593 }
2594
2595 /* DAC mode clear */
2596 F2612->dacen = 0;
2597 F2612->dac_test = 0;
2598 F2612->dacout = 0;
2599
2600 if (F2612->WaveOutMode == 0x02)
2601 F2612->WaveOutMode >>= 1;
2602 }
2603
2604 /* YM2612 write */
2605 /* n = number */
2606 /* a = address */
2607 /* v = value */
ym2612_write(void * chip,int a,UINT8 v)2608 int ym2612_write(void *chip, int a, UINT8 v)
2609 {
2610 YM2612 *F2612 = (YM2612 *)chip;
2611 int addr;
2612
2613 v &= 0xff; /* adjust to 8 bit bus */
2614
2615 switch( a&3)
2616 {
2617 case 0: /* address port 0 */
2618 F2612->OPN.ST.address = v;
2619 F2612->addr_A1 = 0;
2620 break;
2621
2622 case 1: /* data port 0 */
2623 if (F2612->addr_A1 != 0)
2624 break; /* verified on real YM2608 */
2625
2626 addr = F2612->OPN.ST.address;
2627 F2612->REGS[addr] = v;
2628 switch( addr & 0xf0 )
2629 {
2630 case 0x20: /* 0x20-0x2f Mode */
2631 switch( addr )
2632 {
2633 case 0x2a: /* DAC data (YM2612) */
2634 ym2612_update_req(F2612->OPN.ST.param);
2635 F2612->dacout = ((int)v - 0x80) << 6; /* level unknown */
2636 break;
2637 case 0x2b: /* DAC Sel (YM2612) */
2638 /* b7 = dac enable */
2639 F2612->dacen = v & 0x80;
2640 break;
2641 case 0x2C: // undocumented: DAC Test Reg
2642 // b5 = volume enable
2643 F2612->dac_test = v & 0x20;
2644 break;
2645 default: /* OPN section */
2646 ym2612_update_req(F2612->OPN.ST.param);
2647 /* write register */
2648 OPNWriteMode(&(F2612->OPN),addr,v);
2649 }
2650 break;
2651 default: /* 0x30-0xff OPN section */
2652 ym2612_update_req(F2612->OPN.ST.param);
2653 /* write register */
2654 OPNWriteReg(&(F2612->OPN),addr,v);
2655 }
2656 break;
2657
2658 case 2: /* address port 1 */
2659 F2612->OPN.ST.address = v;
2660 F2612->addr_A1 = 1;
2661 break;
2662
2663 case 3: /* data port 1 */
2664 if (F2612->addr_A1 != 1)
2665 break; /* verified on real YM2608 */
2666
2667 addr = F2612->OPN.ST.address;
2668 F2612->REGS[addr | 0x100] = v;
2669 ym2612_update_req(F2612->OPN.ST.param);
2670 OPNWriteReg(&(F2612->OPN),addr | 0x100,v);
2671 break;
2672 }
2673 return F2612->OPN.ST.irq;
2674 }
2675
ym2612_read(void * chip,int a)2676 UINT8 ym2612_read(void *chip,int a)
2677 {
2678 YM2612 *F2612 = (YM2612 *)chip;
2679
2680 switch( a&3)
2681 {
2682 case 0: /* status 0 */
2683 return FM_STATUS_FLAG(&F2612->OPN.ST);
2684 case 1:
2685 case 2:
2686 case 3:
2687 //LOG(LOG_WAR,("YM2612 #%p:A=%d read unmapped area\n",F2612->OPN.ST.param,a));
2688 return FM_STATUS_FLAG(&F2612->OPN.ST);
2689 }
2690 return 0;
2691 }
2692
ym2612_timer_over(void * chip,int c)2693 int ym2612_timer_over(void *chip,int c)
2694 {
2695 YM2612 *F2612 = (YM2612 *)chip;
2696
2697 if( c )
2698 { /* Timer B */
2699 TimerBOver( &(F2612->OPN.ST) );
2700 }
2701 else
2702 { /* Timer A */
2703 ym2612_update_req(F2612->OPN.ST.param);
2704 /* timer update */
2705 TimerAOver( &(F2612->OPN.ST) );
2706 /* CSM mode key,TL controll */
2707 if ((F2612->OPN.ST.mode & 0xc0) == 0x80)
2708 { /* CSM mode total level latch and auto key on */
2709 CSMKeyControll( &F2612->OPN, &(F2612->CH[2]) );
2710 }
2711 }
2712 return F2612->OPN.ST.irq;
2713 }
2714
2715
ym2612_set_mutemask(void * chip,UINT32 MuteMask)2716 void ym2612_set_mutemask(void *chip, UINT32 MuteMask)
2717 {
2718 YM2612 *F2612 = (YM2612 *)chip;
2719 UINT8 CurChn;
2720
2721 for (CurChn = 0; CurChn < 6; CurChn ++)
2722 F2612->CH[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
2723 F2612->MuteDAC = (MuteMask >> 6) & 0x01;
2724
2725 return;
2726 }
2727
2728 #endif /* (BUILD_YM2612||BUILD_YM3238) */
2729