1 #define YM2610B_WARNING
2
3 /*
4 **
5 ** File: fm.c -- software implementation of Yamaha FM sound generator
6 **
7 ** Copyright Jarek Burczynski (bujar at mame dot net)
8 ** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development
9 **
10 ** Version 1.4.2 (final beta)
11 **
12 */
13
14 /*
15 ** History:
16 **
17 ** 2006-2008 Eke-Eke (Genesis Plus GX), MAME backport by R. Belmont.
18 ** - implemented PG overflow, aka "detune bug" (Ariel, Comix Zone, Shaq Fu, Spiderman,...), credits to Nemesis
19 ** - fixed SSG-EG support, credits to Nemesis and additional fixes from Alone Coder
20 ** - modified EG rates and frequency, tested by Nemesis on real hardware
21 ** - implemented LFO phase update for CH3 special mode (Warlock birds, Alladin bug sound)
22 ** - fixed Attack Rate update (Batman & Robin intro)
23 ** - fixed attenuation level at the start of Substain (Gynoug explosions)
24 ** - fixed EG decay->substain transition to handle special cases, like SL=0 and Decay rate is very slow (Mega Turrican tracks 03,09...)
25 **
26 ** 06-23-2007 Zsolt Vasvari:
27 ** - changed the timing not to require the use of floating point calculations
28 **
29 ** 03-08-2003 Jarek Burczynski:
30 ** - fixed YM2608 initial values (after the reset)
31 ** - fixed flag and irqmask handling (YM2608)
32 ** - fixed BUFRDY flag handling (YM2608)
33 **
34 ** 14-06-2003 Jarek Burczynski:
35 ** - implemented all of the YM2608 status register flags
36 ** - implemented support for external memory read/write via YM2608
37 ** - implemented support for deltat memory limit register in YM2608 emulation
38 **
39 ** 22-05-2003 Jarek Burczynski:
40 ** - fixed LFO PM calculations (copy&paste bugfix)
41 **
42 ** 08-05-2003 Jarek Burczynski:
43 ** - fixed SSG support
44 **
45 ** 22-04-2003 Jarek Burczynski:
46 ** - implemented 100% correct LFO generator (verified on real YM2610 and YM2608)
47 **
48 ** 15-04-2003 Jarek Burczynski:
49 ** - added support for YM2608's register 0x110 - status mask
50 **
51 ** 01-12-2002 Jarek Burczynski:
52 ** - fixed register addressing in YM2608, YM2610, YM2610B chips. (verified on real YM2608)
53 ** The addressing patch used for early Neo-Geo games can be removed now.
54 **
55 ** 26-11-2002 Jarek Burczynski, Nicola Salmoria:
56 ** - recreated YM2608 ADPCM ROM using data from real YM2608's output which leads to:
57 ** - added emulation of YM2608 drums.
58 ** - output of YM2608 is two times lower now - same as YM2610 (verified on real YM2608)
59 **
60 ** 16-08-2002 Jarek Burczynski:
61 ** - binary exact Envelope Generator (verified on real YM2203);
62 ** identical to YM2151
63 ** - corrected 'off by one' error in feedback calculations (when feedback is off)
64 ** - corrected connection (algorithm) calculation (verified on real YM2203 and YM2610)
65 **
66 ** 18-12-2001 Jarek Burczynski:
67 ** - added SSG-EG support (verified on real YM2203)
68 **
69 ** 12-08-2001 Jarek Burczynski:
70 ** - corrected sin_tab and tl_tab data (verified on real chip)
71 ** - corrected feedback calculations (verified on real chip)
72 ** - corrected phase generator calculations (verified on real chip)
73 ** - corrected envelope generator calculations (verified on real chip)
74 ** - corrected FM volume level (YM2610 and YM2610B).
75 ** - changed YMxxxUpdateOne() functions (YM2203, YM2608, YM2610, YM2610B, YM2612) :
76 ** this was needed to calculate YM2610 FM channels output correctly.
77 ** (Each FM channel is calculated as in other chips, but the output of the channel
78 ** gets shifted right by one *before* sending to accumulator. That was impossible to do
79 ** with previous implementation).
80 **
81 ** 23-07-2001 Jarek Burczynski, Nicola Salmoria:
82 ** - corrected YM2610 ADPCM type A algorithm and tables (verified on real chip)
83 **
84 ** 11-06-2001 Jarek Burczynski:
85 ** - corrected end of sample bug in ADPCMA_calc_cha().
86 ** Real YM2610 checks for equality between current and end addresses (only 20 LSB bits).
87 **
88 ** 08-12-98 hiro-shi:
89 ** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA
90 ** move ROM limit check.(CALC_CH? -> 2610Write1/2)
91 ** test program (ADPCMB_TEST)
92 ** move ADPCM A/B end check.
93 ** ADPCMB repeat flag(no check)
94 ** change ADPCM volume rate (8->16) (32->48).
95 **
96 ** 09-12-98 hiro-shi:
97 ** change ADPCM volume. (8->16, 48->64)
98 ** replace ym2610 ch0/3 (YM-2610B)
99 ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
100 ** add ADPCM_SHIFT_MASK
101 ** change ADPCMA_DECODE_MIN/MAX.
102 */
103
104
105
106
107 /************************************************************************/
108 /* comment of hiro-shi(Hiromitsu Shioya) */
109 /* YM2610(B) = OPN-B */
110 /* YM2610 : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
111 /* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
112 /************************************************************************/
113
114 #include <stdio.h>
115 #include <stdlib.h>
116 #include <string.h>
117 #include <stdarg.h>
118 #include <math.h>
119 #include <stdlib.h>
120
121 #include "mamedef.h"
122 //#ifndef __RAINE__
123 //#include "sndintrf.h" /* use M.A.M.E. */
124 //#else
125 //#include "deftypes.h" /* use RAINE */
126 //#include "support.h" /* use RAINE */
127 //#endif
128 #include "fm.h"
129
130
131 /* include external DELTA-T unit (when needed) */
132 #if (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
133 #include "ymdeltat.h"
134 #endif
135
136 /* shared function building option */
137 #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
138 #define BUILD_OPN_PRESCALER (BUILD_YM2203||BUILD_YM2608)
139
140
141 /* globals */
142 #define TYPE_SSG 0x01 /* SSG support */
143 #define TYPE_LFOPAN 0x02 /* OPN type LFO and PAN */
144 #define TYPE_6CH 0x04 /* FM 6CH / 3CH */
145 #define TYPE_DAC 0x08 /* YM2612's DAC device */
146 #define TYPE_ADPCM 0x10 /* two ADPCM units */
147 #define TYPE_2610 0x20 /* bogus flag to differentiate 2608 from 2610 */
148
149
150 #define TYPE_YM2203 (TYPE_SSG)
151 #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
152 #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM |TYPE_2610)
153
154
155
156 #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
157 #define EG_SH 16 /* 16.16 fixed point (envelope generator timing) */
158 #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
159 #define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
160
161 #define FREQ_MASK ((1<<FREQ_SH)-1)
162
163 #define ENV_BITS 10
164 #define ENV_LEN (1<<ENV_BITS)
165 #define ENV_STEP (128.0/ENV_LEN)
166
167 #define MAX_ATT_INDEX (ENV_LEN-1) /* 1023 */
168 #define MIN_ATT_INDEX (0) /* 0 */
169
170 #define EG_ATT 4
171 #define EG_DEC 3
172 #define EG_SUS 2
173 #define EG_REL 1
174 #define EG_OFF 0
175
176 #define SIN_BITS 10
177 #define SIN_LEN (1<<SIN_BITS)
178 #define SIN_MASK (SIN_LEN-1)
179
180 #define TL_RES_LEN (256) /* 8 bits addressing (real chip) */
181
182
183 #if (FM_SAMPLE_BITS==16)
184 #define FINAL_SH (0)
185 #define MAXOUT (+32767)
186 #define MINOUT (-32768)
187 #else
188 #define FINAL_SH (8)
189 #define MAXOUT (+127)
190 #define MINOUT (-128)
191 #endif
192
193
194 /* TL_TAB_LEN is calculated as:
195 * 13 - sinus amplitude bits (Y axis)
196 * 2 - sinus sign bit (Y axis)
197 * TL_RES_LEN - sinus resolution (X axis)
198 */
199 #define TL_TAB_LEN (13*2*TL_RES_LEN)
200 static signed int tl_tab[TL_TAB_LEN];
201
202 #define ENV_QUIET (TL_TAB_LEN>>3)
203
204 /* sin waveform table in 'decibel' scale */
205 static unsigned int sin_tab[SIN_LEN];
206
207 /* sustain level table (3dB per step) */
208 /* bit0, bit1, bit2, bit3, bit4, bit5, bit6 */
209 /* 1, 2, 4, 8, 16, 32, 64 (value)*/
210 /* 0.75, 1.5, 3, 6, 12, 24, 48 (dB)*/
211
212 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
213 #define SC(db) (UINT32) ( db * (4.0/ENV_STEP) )
214 static const UINT32 sl_table[16]={
215 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
216 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
217 };
218 #undef SC
219
220
221 #define RATE_STEPS (8)
222 static const UINT8 eg_inc[19*RATE_STEPS]={
223
224 /*cycle:0 1 2 3 4 5 6 7*/
225
226 /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..11 0 (increment by 0 or 1) */
227 /* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..11 1 */
228 /* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..11 2 */
229 /* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..11 3 */
230
231 /* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 12 0 (increment by 1) */
232 /* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 12 1 */
233 /* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 12 2 */
234 /* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 12 3 */
235
236 /* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 13 0 (increment by 2) */
237 /* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 13 1 */
238 /*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 13 2 */
239 /*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 13 3 */
240
241 /*12 */ 4,4, 4,4, 4,4, 4,4, /* rate 14 0 (increment by 4) */
242 /*13 */ 4,4, 4,8, 4,4, 4,8, /* rate 14 1 */
243 /*14 */ 4,8, 4,8, 4,8, 4,8, /* rate 14 2 */
244 /*15 */ 4,8, 8,8, 4,8, 8,8, /* rate 14 3 */
245
246 /*16 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */
247 /*17 */ 16,16,16,16,16,16,16,16, /* rates 15 2, 15 3 for attack */
248 /*18 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
249 };
250
251
252 #define O(a) (a*RATE_STEPS)
253
254 /*note that there is no O(17) in this table - it's directly in the code */
255 static const UINT8 eg_rate_select[32+64+32]={ /* Envelope Generator rates (32 + 64 rates + 32 RKS) */
256 /* 32 infinite time rates */
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 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
261
262 /* rates 00-11 */
263 O( 0),O( 1),O( 2),O( 3),
264 O( 0),O( 1),O( 2),O( 3),
265 O( 0),O( 1),O( 2),O( 3),
266 O( 0),O( 1),O( 2),O( 3),
267 O( 0),O( 1),O( 2),O( 3),
268 O( 0),O( 1),O( 2),O( 3),
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
276 /* rate 12 */
277 O( 4),O( 5),O( 6),O( 7),
278
279 /* rate 13 */
280 O( 8),O( 9),O(10),O(11),
281
282 /* rate 14 */
283 O(12),O(13),O(14),O(15),
284
285 /* rate 15 */
286 O(16),O(16),O(16),O(16),
287
288 /* 32 dummy rates (same as 15 3) */
289 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
290 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
291 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
292 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
293
294 };
295
296 #undef O
297
298 /*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15*/
299 /*shift 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0 */
300 /*mask 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0, 0 */
301
302 #define O(a) (a*1)
303 static const UINT8 eg_rate_shift[32+64+32]={ /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */
304 /* 32 infinite time rates */
305 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
306 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
307 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
308 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
309
310 /* rates 00-11 */
311 O(11),O(11),O(11),O(11),
312 O(10),O(10),O(10),O(10),
313 O( 9),O( 9),O( 9),O( 9),
314 O( 8),O( 8),O( 8),O( 8),
315 O( 7),O( 7),O( 7),O( 7),
316 O( 6),O( 6),O( 6),O( 6),
317 O( 5),O( 5),O( 5),O( 5),
318 O( 4),O( 4),O( 4),O( 4),
319 O( 3),O( 3),O( 3),O( 3),
320 O( 2),O( 2),O( 2),O( 2),
321 O( 1),O( 1),O( 1),O( 1),
322 O( 0),O( 0),O( 0),O( 0),
323
324 /* rate 12 */
325 O( 0),O( 0),O( 0),O( 0),
326
327 /* rate 13 */
328 O( 0),O( 0),O( 0),O( 0),
329
330 /* rate 14 */
331 O( 0),O( 0),O( 0),O( 0),
332
333 /* rate 15 */
334 O( 0),O( 0),O( 0),O( 0),
335
336 /* 32 dummy rates (same as 15 3) */
337 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
338 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
339 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
340 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0)
341
342 };
343 #undef O
344
345 static const UINT8 dt_tab[4 * 32]={
346 /* this is YM2151 and YM2612 phase increment data (in 10.10 fixed point format)*/
347 /* FD=0 */
348 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
349 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
350 /* FD=1 */
351 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
352 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
353 /* FD=2 */
354 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
355 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
356 /* FD=3 */
357 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
358 8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
359 };
360
361
362 /* OPN key frequency number -> key code follow table */
363 /* fnum higher 4bit -> keycode lower 2bit */
364 static const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
365
366
367 /* 8 LFO speed parameters */
368 /* each value represents number of samples that one LFO level will last for */
369 static const UINT32 lfo_samples_per_step[8] = {108, 77, 71, 67, 62, 44, 8, 5};
370
371
372
373 /*There are 4 different LFO AM depths available, they are:
374 0 dB, 1.4 dB, 5.9 dB, 11.8 dB
375 Here is how it is generated (in EG steps):
376
377 11.8 dB = 0, 2, 4, 6, 8, 10,12,14,16...126,126,124,122,120,118,....4,2,0
378 5.9 dB = 0, 1, 2, 3, 4, 5, 6, 7, 8....63, 63, 62, 61, 60, 59,.....2,1,0
379 1.4 dB = 0, 0, 0, 0, 1, 1, 1, 1, 2,...15, 15, 15, 15, 14, 14,.....0,0,0
380
381 (1.4 dB is losing precision as you can see)
382
383 It's implemented as generator from 0..126 with step 2 then a shift
384 right N times, where N is:
385 8 for 0 dB
386 3 for 1.4 dB
387 1 for 5.9 dB
388 0 for 11.8 dB
389 */
390 static const UINT8 lfo_ams_depth_shift[4] = {8, 3, 1, 0};
391
392
393
394 /*There are 8 different LFO PM depths available, they are:
395 0, 3.4, 6.7, 10, 14, 20, 40, 80 (cents)
396
397 Modulation level at each depth depends on F-NUMBER bits: 4,5,6,7,8,9,10
398 (bits 8,9,10 = FNUM MSB from OCT/FNUM register)
399
400 Here we store only first quarter (positive one) of full waveform.
401 Full table (lfo_pm_table) containing all 128 waveforms is build
402 at run (init) time.
403
404 One value in table below represents 4 (four) basic LFO steps
405 (1 PM step = 4 AM steps).
406
407 For example:
408 at LFO SPEED=0 (which is 108 samples per basic LFO step)
409 one value from "lfo_pm_output" table lasts for 432 consecutive
410 samples (4*108=432) and one full LFO waveform cycle lasts for 13824
411 samples (32*432=13824; 32 because we store only a quarter of whole
412 waveform in the table below)
413 */
414 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 */
415 /* FNUM BIT 4: 000 0001xxxx */
416 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
417 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
418 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
419 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
420 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0},
421 /* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0},
422 /* DEPTH 6 */ {0, 0, 0, 0, 0, 0, 0, 0},
423 /* DEPTH 7 */ {0, 0, 0, 0, 1, 1, 1, 1},
424
425 /* FNUM BIT 5: 000 0010xxxx */
426 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
427 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
428 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
429 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
430 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0},
431 /* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0},
432 /* DEPTH 6 */ {0, 0, 0, 0, 1, 1, 1, 1},
433 /* DEPTH 7 */ {0, 0, 1, 1, 2, 2, 2, 3},
434
435 /* FNUM BIT 6: 000 0100xxxx */
436 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
437 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
438 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
439 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
440 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 1},
441 /* DEPTH 5 */ {0, 0, 0, 0, 1, 1, 1, 1},
442 /* DEPTH 6 */ {0, 0, 1, 1, 2, 2, 2, 3},
443 /* DEPTH 7 */ {0, 0, 2, 3, 4, 4, 5, 6},
444
445 /* FNUM BIT 7: 000 1000xxxx */
446 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
447 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
448 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 1, 1},
449 /* DEPTH 3 */ {0, 0, 0, 0, 1, 1, 1, 1},
450 /* DEPTH 4 */ {0, 0, 0, 1, 1, 1, 1, 2},
451 /* DEPTH 5 */ {0, 0, 1, 1, 2, 2, 2, 3},
452 /* DEPTH 6 */ {0, 0, 2, 3, 4, 4, 5, 6},
453 /* DEPTH 7 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
454
455 /* FNUM BIT 8: 001 0000xxxx */
456 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
457 /* DEPTH 1 */ {0, 0, 0, 0, 1, 1, 1, 1},
458 /* DEPTH 2 */ {0, 0, 0, 1, 1, 1, 2, 2},
459 /* DEPTH 3 */ {0, 0, 1, 1, 2, 2, 3, 3},
460 /* DEPTH 4 */ {0, 0, 1, 2, 2, 2, 3, 4},
461 /* DEPTH 5 */ {0, 0, 2, 3, 4, 4, 5, 6},
462 /* DEPTH 6 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
463 /* DEPTH 7 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
464
465 /* FNUM BIT 9: 010 0000xxxx */
466 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
467 /* DEPTH 1 */ {0, 0, 0, 0, 2, 2, 2, 2},
468 /* DEPTH 2 */ {0, 0, 0, 2, 2, 2, 4, 4},
469 /* DEPTH 3 */ {0, 0, 2, 2, 4, 4, 6, 6},
470 /* DEPTH 4 */ {0, 0, 2, 4, 4, 4, 6, 8},
471 /* DEPTH 5 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
472 /* DEPTH 6 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
473 /* DEPTH 7 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30},
474
475 /* FNUM BIT10: 100 0000xxxx */
476 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
477 /* DEPTH 1 */ {0, 0, 0, 0, 4, 4, 4, 4},
478 /* DEPTH 2 */ {0, 0, 0, 4, 4, 4, 8, 8},
479 /* DEPTH 3 */ {0, 0, 4, 4, 8, 8, 0xc, 0xc},
480 /* DEPTH 4 */ {0, 0, 4, 8, 8, 8, 0xc,0x10},
481 /* DEPTH 5 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
482 /* DEPTH 6 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30},
483 /* DEPTH 7 */ {0, 0,0x20,0x30,0x40,0x40,0x50,0x60},
484
485 };
486
487 /* all 128 LFO PM waveforms */
488 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 */
489
490
491
492
493
494 /* register number to channel number , slot offset */
495 #define OPN_CHAN(N) (N&3)
496 #define OPN_SLOT(N) ((N>>2)&3)
497
498 /* slot number */
499 #define SLOT1 0
500 #define SLOT2 2
501 #define SLOT3 1
502 #define SLOT4 3
503
504 /* bit0 = Right enable , bit1 = Left enable */
505 #define OUTD_RIGHT 1
506 #define OUTD_LEFT 2
507 #define OUTD_CENTER 3
508
509
510 /* save output as raw 16-bit sample */
511 /* #define SAVE_SAMPLE */
512
513 #ifdef SAVE_SAMPLE
514 static FILE *sample[1];
515 #if 1 /*save to MONO file */
516 #define SAVE_ALL_CHANNELS \
517 { signed int pom = lt; \
518 fputc((unsigned short)pom&0xff,sample[0]); \
519 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
520 }
521 #else /*save to STEREO file */
522 #define SAVE_ALL_CHANNELS \
523 { signed int pom = lt; \
524 fputc((unsigned short)pom&0xff,sample[0]); \
525 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
526 pom = rt; \
527 fputc((unsigned short)pom&0xff,sample[0]); \
528 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
529 }
530 #endif
531 #endif
532
533
534 /* struct describing a single operator (SLOT) */
535 typedef struct
536 {
537 INT32 *DT; /* detune :dt_tab[DT] */
538 UINT8 KSR; /* key scale rate :3-KSR */
539 UINT32 ar; /* attack rate */
540 UINT32 d1r; /* decay rate */
541 UINT32 d2r; /* sustain rate */
542 UINT32 rr; /* release rate */
543 UINT8 ksr; /* key scale rate :kcode>>(3-KSR) */
544 UINT32 mul; /* multiple :ML_TABLE[ML] */
545
546 /* Phase Generator */
547 UINT32 phase; /* phase counter */
548 INT32 Incr; /* phase step */
549
550 /* Envelope Generator */
551 UINT8 state; /* phase type */
552 UINT32 tl; /* total level: TL << 3 */
553 INT32 volume; /* envelope counter */
554 UINT32 sl; /* sustain level:sl_table[SL] */
555 UINT32 vol_out; /* current output from EG circuit (without AM from LFO) */
556
557 UINT8 eg_sh_ar; /* (attack state) */
558 UINT8 eg_sel_ar; /* (attack state) */
559 UINT8 eg_sh_d1r; /* (decay state) */
560 UINT8 eg_sel_d1r; /* (decay state) */
561 UINT8 eg_sh_d2r; /* (sustain state) */
562 UINT8 eg_sel_d2r; /* (sustain state) */
563 UINT8 eg_sh_rr; /* (release state) */
564 UINT8 eg_sel_rr; /* (release state) */
565
566 UINT8 ssg; /* SSG-EG waveform */
567 UINT8 ssgn; /* SSG-EG negated output */
568
569 UINT32 key; /* 0=last key was KEY OFF, 1=KEY ON */
570
571 /* LFO */
572 UINT32 AMmask; /* AM enable flag */
573
574 } FM_SLOT;
575
576 typedef struct
577 {
578 FM_SLOT SLOT[4]; /* four SLOTs (operators) */
579
580 UINT8 ALGO; /* algorithm */
581 UINT8 FB; /* feedback shift */
582 INT32 op1_out[2]; /* op1 output for feedback */
583
584 INT32 *connect1; /* SLOT1 output pointer */
585 INT32 *connect3; /* SLOT3 output pointer */
586 INT32 *connect2; /* SLOT2 output pointer */
587 INT32 *connect4; /* SLOT4 output pointer */
588
589 INT32 *mem_connect;/* where to put the delayed sample (MEM) */
590 INT32 mem_value; /* delayed sample (MEM) value */
591
592 INT32 pms; /* channel PMS */
593 UINT8 ams; /* channel AMS */
594
595 UINT32 fc; /* fnum,blk:adjusted to sample rate */
596 UINT8 kcode; /* key code: */
597 UINT32 block_fnum; /* current blk/fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
598 UINT8 Muted;
599 } FM_CH;
600
601
602 typedef struct
603 {
604 //const device_config *device;
605 void * param; /* this chip parameter */
606 int clock; /* master clock (Hz) */
607 int rate; /* sampling rate (Hz) */
608 double freqbase; /* frequency base */
609 int timer_prescaler; /* timer prescaler */
610 #if FM_BUSY_FLAG_SUPPORT
611 TIME_TYPE busy_expiry_time; /* expiry time of the busy status */
612 #endif
613 UINT8 address; /* address register */
614 UINT8 irq; /* interrupt level */
615 UINT8 irqmask; /* irq mask */
616 UINT8 status; /* status flag */
617 UINT32 mode; /* mode CSM / 3SLOT */
618 UINT8 prescaler_sel; /* prescaler selector */
619 UINT8 fn_h; /* freq latch */
620 INT32 TA; /* timer a */
621 INT32 TAC; /* timer a counter */
622 UINT8 TB; /* timer b */
623 INT32 TBC; /* timer b counter */
624 /* local time tables */
625 INT32 dt_tab[8][32]; /* DeTune table */
626 /* Extention Timer and IRQ handler */
627 FM_TIMERHANDLER timer_handler;
628 FM_IRQHANDLER IRQ_Handler;
629 const ssg_callbacks *SSG;
630 } FM_ST;
631
632
633
634 /***********************************************************/
635 /* OPN unit */
636 /***********************************************************/
637
638 /* OPN 3slot struct */
639 typedef struct
640 {
641 UINT32 fc[3]; /* fnum3,blk3: calculated */
642 UINT8 fn_h; /* freq3 latch */
643 UINT8 kcode[3]; /* key code */
644 UINT32 block_fnum[3]; /* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
645 } FM_3SLOT;
646
647 /* OPN/A/B common state */
648 typedef struct
649 {
650 UINT8 type; /* chip type */
651 FM_ST ST; /* general state */
652 FM_3SLOT SL3; /* 3 slot mode state */
653 FM_CH *P_CH; /* pointer of CH */
654 unsigned int pan[6*2]; /* fm channels output masks (0xffffffff = enable) */
655
656 UINT32 eg_cnt; /* global envelope generator counter */
657 UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/64/3 */
658 UINT32 eg_timer_add; /* step of eg_timer */
659 UINT32 eg_timer_overflow;/* envelope generator timer overlfows every 3 samples (on real chip) */
660
661
662 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
663 but LFO works with one more bit of a precision so we really need 4096 elements */
664
665 UINT32 fn_table[4096]; /* fnumber->increment counter */
666 UINT32 fn_max; /* maximal phase increment (used for phase overflow) */
667
668 /* LFO */
669 UINT32 LFO_AM; /* runtime LFO calculations helper */
670 INT32 LFO_PM; /* runtime LFO calculations helper */
671
672 UINT32 lfo_cnt;
673 UINT32 lfo_inc;
674
675 UINT32 lfo_freq[8]; /* LFO FREQ table */
676
677 INT32 m2,c1,c2; /* Phase Modulation input for operators 2,3,4 */
678 INT32 mem; /* one sample delay memory */
679
680 INT32 out_fm[8]; /* outputs of working channels */
681
682 #if (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
683 INT32 out_adpcm[4]; /* channel output NONE,LEFT,RIGHT or CENTER for YM2608/YM2610 ADPCM */
684 INT32 out_delta[4]; /* channel output NONE,LEFT,RIGHT or CENTER for YM2608/YM2610 DELTAT*/
685 #endif
686 } FM_OPN;
687
688
689
690 /* log output level */
691 #define LOG_ERR 3 /* ERROR */
692 #define LOG_WAR 2 /* WARNING */
693 #define LOG_INF 1 /* INFORMATION */
694 #define LOG_LEVEL LOG_INF
695
696 #ifndef __RAINE__
697 #define LOG(n,x) do { if( (n)>=LOG_LEVEL ) logerror x; } while (0)
698 #endif
699
700 /* limitter */
701 #define Limit(val, max,min) { \
702 if ( val > max ) val = max; \
703 else if ( val < min ) val = min; \
704 }
705
706
707 /* status set and IRQ handling */
FM_STATUS_SET(FM_ST * ST,int flag)708 INLINE void FM_STATUS_SET(FM_ST *ST,int flag)
709 {
710 /* set status flag */
711 ST->status |= flag;
712 if ( !(ST->irq) && (ST->status & ST->irqmask) )
713 {
714 ST->irq = 1;
715 /* callback user interrupt handler (IRQ is OFF to ON) */
716 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->param,1);
717 }
718 }
719
720 /* status reset and IRQ handling */
FM_STATUS_RESET(FM_ST * ST,int flag)721 INLINE void FM_STATUS_RESET(FM_ST *ST,int flag)
722 {
723 /* reset status flag */
724 ST->status &=~flag;
725 if ( (ST->irq) && !(ST->status & ST->irqmask) )
726 {
727 ST->irq = 0;
728 /* callback user interrupt handler (IRQ is ON to OFF) */
729 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->param,0);
730 }
731 }
732
733 /* IRQ mask set */
FM_IRQMASK_SET(FM_ST * ST,int flag)734 INLINE void FM_IRQMASK_SET(FM_ST *ST,int flag)
735 {
736 ST->irqmask = flag;
737 /* IRQ handling check */
738 FM_STATUS_SET(ST,0);
739 FM_STATUS_RESET(ST,0);
740 }
741
742 /* OPN Mode Register Write */
set_timers(FM_ST * ST,void * n,int v)743 INLINE void set_timers( FM_ST *ST, void *n, int v )
744 {
745 /* b7 = CSM MODE */
746 /* b6 = 3 slot mode */
747 /* b5 = reset b */
748 /* b4 = reset a */
749 /* b3 = timer enable b */
750 /* b2 = timer enable a */
751 /* b1 = load b */
752 /* b0 = load a */
753 ST->mode = v;
754
755 /* reset Timer b flag */
756 if( v & 0x20 )
757 FM_STATUS_RESET(ST,0x02);
758 /* reset Timer a flag */
759 if( v & 0x10 )
760 FM_STATUS_RESET(ST,0x01);
761 /* load b */
762 if( v & 0x02 )
763 {
764 if( ST->TBC == 0 )
765 {
766 ST->TBC = ( 256-ST->TB)<<4;
767 /* External timer handler */
768 if (ST->timer_handler) (ST->timer_handler)(n,1,ST->TBC * ST->timer_prescaler,ST->clock);
769 }
770 }
771 else
772 { /* stop timer b */
773 if( ST->TBC != 0 )
774 {
775 ST->TBC = 0;
776 if (ST->timer_handler) (ST->timer_handler)(n,1,0,ST->clock);
777 }
778 }
779 /* load a */
780 if( v & 0x01 )
781 {
782 if( ST->TAC == 0 )
783 {
784 ST->TAC = (1024-ST->TA);
785 /* External timer handler */
786 if (ST->timer_handler) (ST->timer_handler)(n,0,ST->TAC * ST->timer_prescaler,ST->clock);
787 }
788 }
789 else
790 { /* stop timer a */
791 if( ST->TAC != 0 )
792 {
793 ST->TAC = 0;
794 if (ST->timer_handler) (ST->timer_handler)(n,0,0,ST->clock);
795 }
796 }
797 }
798
799
800 /* Timer A Overflow */
TimerAOver(FM_ST * ST)801 INLINE void TimerAOver(FM_ST *ST)
802 {
803 /* set status (if enabled) */
804 if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
805 /* clear or reload the counter */
806 ST->TAC = (1024-ST->TA);
807 if (ST->timer_handler) (ST->timer_handler)(ST->param,0,ST->TAC * ST->timer_prescaler,ST->clock);
808 }
809 /* Timer B Overflow */
TimerBOver(FM_ST * ST)810 INLINE void TimerBOver(FM_ST *ST)
811 {
812 /* set status (if enabled) */
813 if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
814 /* clear or reload the counter */
815 ST->TBC = ( 256-ST->TB)<<4;
816 if (ST->timer_handler) (ST->timer_handler)(ST->param,1,ST->TBC * ST->timer_prescaler,ST->clock);
817 }
818
819
820 #if FM_INTERNAL_TIMER
821 /* ----- internal timer mode , update timer */
822
823 /* ---------- calculate timer A ---------- */
824 #define INTERNAL_TIMER_A(ST,CSM_CH) \
825 { \
826 if( (ST)->TAC && ((ST)->timer_handler==0) ) \
827 if( ((ST)->TAC -= (int)((ST)->freqbase*4096)) <= 0 ) \
828 { \
829 TimerAOver( ST ); \
830 /* CSM mode total level latch and auto key on */ \
831 if( (ST)->mode & 0x80 ) \
832 CSMKeyControll( OPN->type, CSM_CH ); \
833 } \
834 }
835 /* ---------- calculate timer B ---------- */
836 #define INTERNAL_TIMER_B(ST,step) \
837 { \
838 if( (ST)->TBC && ((ST)->timer_handler==0) ) \
839 if( ((ST)->TBC -= (int)((ST)->freqbase*4096*step)) <= 0 ) \
840 TimerBOver( ST ); \
841 }
842 #else /* FM_INTERNAL_TIMER */
843 /* external timer mode */
844 #define INTERNAL_TIMER_A(ST,CSM_CH)
845 #define INTERNAL_TIMER_B(ST,step)
846 #endif /* FM_INTERNAL_TIMER */
847
848
849
850 #if FM_BUSY_FLAG_SUPPORT
851 #define FM_BUSY_CLEAR(ST) ((ST)->busy_expiry_time = UNDEFINED_TIME)
FM_STATUS_FLAG(FM_ST * ST)852 INLINE UINT8 FM_STATUS_FLAG(FM_ST *ST)
853 {
854 if( COMPARE_TIMES(ST->busy_expiry_time, UNDEFINED_TIME) != 0 )
855 {
856 if (COMPARE_TIMES(ST->busy_expiry_time, FM_GET_TIME_NOW(ST->device->machine)) > 0)
857 return ST->status | 0x80; /* with busy */
858 /* expire */
859 FM_BUSY_CLEAR(ST);
860 }
861 return ST->status;
862 }
FM_BUSY_SET(FM_ST * ST,int busyclock)863 INLINE void FM_BUSY_SET(FM_ST *ST,int busyclock )
864 {
865 TIME_TYPE expiry_period = MULTIPLY_TIME_BY_INT(ATTOTIME_IN_HZ(ST->clock), busyclock * ST->timer_prescaler);
866 ST->busy_expiry_time = ADD_TIMES(FM_GET_TIME_NOW(ST->device->machine), expiry_period);
867 }
868 #else
869 #define FM_STATUS_FLAG(ST) ((ST)->status)
870 #define FM_BUSY_SET(ST,bclock) {}
871 #define FM_BUSY_CLEAR(ST) {}
872 #endif
873
874
875
876
FM_KEYON(UINT8 type,FM_CH * CH,int s)877 INLINE void FM_KEYON(UINT8 type, FM_CH *CH , int s )
878 {
879 FM_SLOT *SLOT = &CH->SLOT[s];
880 if( !SLOT->key )
881 {
882 SLOT->key = 1;
883 SLOT->phase = 0; /* restart Phase Generator */
884 SLOT->ssgn = (SLOT->ssg & 0x04) >> 1;
885 SLOT->state = EG_ATT;
886 }
887 }
888
FM_KEYOFF(FM_CH * CH,int s)889 INLINE void FM_KEYOFF(FM_CH *CH , int s )
890 {
891 FM_SLOT *SLOT = &CH->SLOT[s];
892 if( SLOT->key )
893 {
894 SLOT->key = 0;
895 if (SLOT->state>EG_REL)
896 SLOT->state = EG_REL;/* phase -> Release */
897 }
898 }
899
900 /* set algorithm connection */
setup_connection(FM_OPN * OPN,FM_CH * CH,int ch)901 static void setup_connection( FM_OPN *OPN, FM_CH *CH, int ch )
902 {
903 INT32 *carrier = &OPN->out_fm[ch];
904
905 INT32 **om1 = &CH->connect1;
906 INT32 **om2 = &CH->connect3;
907 INT32 **oc1 = &CH->connect2;
908
909 INT32 **memc = &CH->mem_connect;
910
911 switch( CH->ALGO )
912 {
913 case 0:
914 /* M1---C1---MEM---M2---C2---OUT */
915 *om1 = &OPN->c1;
916 *oc1 = &OPN->mem;
917 *om2 = &OPN->c2;
918 *memc= &OPN->m2;
919 break;
920 case 1:
921 /* M1------+-MEM---M2---C2---OUT */
922 /* C1-+ */
923 *om1 = &OPN->mem;
924 *oc1 = &OPN->mem;
925 *om2 = &OPN->c2;
926 *memc= &OPN->m2;
927 break;
928 case 2:
929 /* M1-----------------+-C2---OUT */
930 /* C1---MEM---M2-+ */
931 *om1 = &OPN->c2;
932 *oc1 = &OPN->mem;
933 *om2 = &OPN->c2;
934 *memc= &OPN->m2;
935 break;
936 case 3:
937 /* M1---C1---MEM------+-C2---OUT */
938 /* M2-+ */
939 *om1 = &OPN->c1;
940 *oc1 = &OPN->mem;
941 *om2 = &OPN->c2;
942 *memc= &OPN->c2;
943 break;
944 case 4:
945 /* M1---C1-+-OUT */
946 /* M2---C2-+ */
947 /* MEM: not used */
948 *om1 = &OPN->c1;
949 *oc1 = carrier;
950 *om2 = &OPN->c2;
951 *memc= &OPN->mem; /* store it anywhere where it will not be used */
952 break;
953 case 5:
954 /* +----C1----+ */
955 /* M1-+-MEM---M2-+-OUT */
956 /* +----C2----+ */
957 *om1 = 0; /* special mark */
958 *oc1 = carrier;
959 *om2 = carrier;
960 *memc= &OPN->m2;
961 break;
962 case 6:
963 /* M1---C1-+ */
964 /* M2-+-OUT */
965 /* C2-+ */
966 /* MEM: not used */
967 *om1 = &OPN->c1;
968 *oc1 = carrier;
969 *om2 = carrier;
970 *memc= &OPN->mem; /* store it anywhere where it will not be used */
971 break;
972 case 7:
973 /* M1-+ */
974 /* C1-+-OUT */
975 /* M2-+ */
976 /* C2-+ */
977 /* MEM: not used*/
978 *om1 = carrier;
979 *oc1 = carrier;
980 *om2 = carrier;
981 *memc= &OPN->mem; /* store it anywhere where it will not be used */
982 break;
983 }
984
985 CH->connect4 = carrier;
986 }
987
988 /* set detune & multiple */
set_det_mul(FM_ST * ST,FM_CH * CH,FM_SLOT * SLOT,int v)989 INLINE void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
990 {
991 SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1;
992 SLOT->DT = ST->dt_tab[(v>>4)&7];
993 CH->SLOT[SLOT1].Incr=-1;
994 }
995
996 /* set total level */
set_tl(FM_CH * CH,FM_SLOT * SLOT,int v)997 INLINE void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v)
998 {
999 SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */
1000 }
1001
1002 /* set attack rate & key scale */
set_ar_ksr(UINT8 type,FM_CH * CH,FM_SLOT * SLOT,int v)1003 INLINE void set_ar_ksr(UINT8 type, FM_CH *CH,FM_SLOT *SLOT,int v)
1004 {
1005 UINT8 old_KSR = SLOT->KSR;
1006
1007 SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1008
1009 SLOT->KSR = 3-(v>>6);
1010 if (SLOT->KSR != old_KSR)
1011 {
1012 CH->SLOT[SLOT1].Incr=-1;
1013 }
1014
1015 /* refresh Attack rate */
1016 if ((SLOT->ar + SLOT->ksr) < 32+62)
1017 {
1018 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1019 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1020 }
1021 else
1022 {
1023 SLOT->eg_sh_ar = 0;
1024 SLOT->eg_sel_ar = 17*RATE_STEPS;
1025 }
1026 }
1027
1028 /* set decay rate */
set_dr(UINT8 type,FM_SLOT * SLOT,int v)1029 INLINE void set_dr(UINT8 type, FM_SLOT *SLOT,int v)
1030 {
1031 SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1032
1033 SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
1034 SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];
1035 }
1036
1037 /* set sustain rate */
set_sr(UINT8 type,FM_SLOT * SLOT,int v)1038 INLINE void set_sr(UINT8 type, FM_SLOT *SLOT,int v)
1039 {
1040 SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1041
1042 SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
1043 SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];
1044 }
1045
1046 /* set release rate */
set_sl_rr(UINT8 type,FM_SLOT * SLOT,int v)1047 INLINE void set_sl_rr(UINT8 type, FM_SLOT *SLOT,int v)
1048 {
1049 SLOT->sl = sl_table[ v>>4 ];
1050
1051 SLOT->rr = 34 + ((v&0x0f)<<2);
1052
1053 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
1054 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr];
1055 }
1056
1057
1058
op_calc(UINT32 phase,unsigned int env,signed int pm)1059 INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm)
1060 {
1061 UINT32 p;
1062
1063 p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + (pm<<15))) >> FREQ_SH ) & SIN_MASK ];
1064
1065 if (p >= TL_TAB_LEN)
1066 return 0;
1067 return tl_tab[p];
1068 }
1069
op_calc1(UINT32 phase,unsigned int env,signed int pm)1070 INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm)
1071 {
1072 UINT32 p;
1073
1074 p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK ];
1075
1076 if (p >= TL_TAB_LEN)
1077 return 0;
1078 return tl_tab[p];
1079 }
1080
1081 /* advance LFO to next sample */
advance_lfo(FM_OPN * OPN)1082 INLINE void advance_lfo(FM_OPN *OPN)
1083 {
1084 UINT8 pos;
1085
1086 if (OPN->lfo_inc) /* LFO enabled ? */
1087 {
1088 OPN->lfo_cnt += OPN->lfo_inc;
1089
1090 pos = (OPN->lfo_cnt >> LFO_SH) & 127;
1091
1092
1093 /* update AM when LFO output changes */
1094
1095 /* actually I can't optimize is this way without rewriting chan_calc()
1096 to use chip->lfo_am instead of global lfo_am */
1097 {
1098
1099 /* triangle */
1100 /* AM: 0 to 126 step +2, 126 to 0 step -2 */
1101 if (pos<64)
1102 OPN->LFO_AM = (pos&63) * 2;
1103 else
1104 OPN->LFO_AM = 126 - ((pos&63) * 2);
1105 }
1106
1107 /* PM works with 4 times slower clock */
1108 pos >>= 2;
1109 /* update PM when LFO output changes */
1110 /*if (prev_pos != pos)*/ /* can't use global lfo_pm for this optimization, must be chip->lfo_pm instead*/
1111 {
1112 OPN->LFO_PM = pos;
1113 }
1114
1115 }
1116 else
1117 {
1118 OPN->LFO_AM = 0;
1119 OPN->LFO_PM = 0;
1120 }
1121 }
1122
1123 /* changed from INLINE to static here to work around gcc 4.2.1 codegen bug */
advance_eg_channel(FM_OPN * OPN,FM_SLOT * SLOT)1124 static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
1125 {
1126 unsigned int out;
1127 unsigned int swap_flag = 0;
1128 unsigned int i;
1129
1130
1131 i = 4; /* four operators per channel */
1132 do
1133 {
1134 /* reset SSG-EG swap flag */
1135 swap_flag = 0;
1136
1137 switch(SLOT->state)
1138 {
1139 case EG_ATT: /* attack phase */
1140 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_ar)-1) ) )
1141 {
1142 SLOT->volume += (~SLOT->volume *
1143 (eg_inc[SLOT->eg_sel_ar + ((OPN->eg_cnt>>SLOT->eg_sh_ar)&7)])
1144 ) >>4;
1145
1146 if (SLOT->volume <= MIN_ATT_INDEX)
1147 {
1148 SLOT->volume = MIN_ATT_INDEX;
1149 SLOT->state = EG_DEC;
1150 }
1151 }
1152 break;
1153
1154 case EG_DEC: /* decay phase */
1155 {
1156 if (SLOT->ssg&0x08) /* SSG EG type envelope selected */
1157 {
1158 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
1159 {
1160 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1161
1162 if ( SLOT->volume >= (INT32)(SLOT->sl) )
1163 SLOT->state = EG_SUS;
1164 }
1165 }
1166 else
1167 {
1168 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
1169 {
1170 SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1171
1172 if ( SLOT->volume >= (INT32)(SLOT->sl) )
1173 SLOT->state = EG_SUS;
1174 }
1175 }
1176 }
1177 break;
1178
1179 case EG_SUS: /* sustain phase */
1180 if (SLOT->ssg&0x08) /* SSG EG type envelope selected */
1181 {
1182 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
1183 {
1184
1185 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1186
1187 if ( SLOT->volume >= ENV_QUIET )
1188 {
1189 SLOT->volume = MAX_ATT_INDEX;
1190
1191 if (SLOT->ssg&0x01) /* bit 0 = hold */
1192 {
1193 if (SLOT->ssgn&1) /* have we swapped once ??? */
1194 {
1195 /* yes, so do nothing, just hold current level */
1196 }
1197 else
1198 swap_flag = (SLOT->ssg&0x02) | 1 ; /* bit 1 = alternate */
1199
1200 }
1201 else
1202 {
1203 /* same as KEY-ON operation */
1204
1205 /* restart of the Phase Generator should be here */
1206 SLOT->phase = 0;
1207
1208 {
1209 /* phase -> Attack */
1210 SLOT->volume = 511;
1211 SLOT->state = EG_ATT;
1212 }
1213
1214 swap_flag = (SLOT->ssg&0x02); /* bit 1 = alternate */
1215 }
1216 }
1217 }
1218 }
1219 else
1220 {
1221 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
1222 {
1223 SLOT->volume += eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1224
1225 if ( SLOT->volume >= MAX_ATT_INDEX )
1226 {
1227 SLOT->volume = MAX_ATT_INDEX;
1228 /* do not change SLOT->state (verified on real chip) */
1229 }
1230 }
1231
1232 }
1233 break;
1234
1235 case EG_REL: /* release phase */
1236 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_rr)-1) ) )
1237 {
1238 /* SSG-EG affects Release phase also (Nemesis) */
1239 SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)];
1240
1241 if ( SLOT->volume >= MAX_ATT_INDEX )
1242 {
1243 SLOT->volume = MAX_ATT_INDEX;
1244 SLOT->state = EG_OFF;
1245 }
1246 }
1247 break;
1248
1249 }
1250
1251
1252 out = ((UINT32)SLOT->volume);
1253
1254 /* negate output (changes come from alternate bit, init comes from attack bit) */
1255 if ((SLOT->ssg&0x08) && (SLOT->ssgn&2) && (SLOT->state > EG_REL))
1256 out ^= MAX_ATT_INDEX;
1257
1258 /* we need to store the result here because we are going to change ssgn
1259 in next instruction */
1260 SLOT->vol_out = out + SLOT->tl;
1261
1262 /* reverse SLOT inversion flag */
1263 SLOT->ssgn ^= swap_flag;
1264
1265 SLOT++;
1266 i--;
1267 }while (i);
1268
1269 }
1270
1271
1272
1273 #define volume_calc(OP) ((OP)->vol_out + (AM & (OP)->AMmask))
1274
update_phase_lfo_slot(FM_OPN * OPN,FM_SLOT * SLOT,INT32 pms,UINT32 block_fnum)1275 INLINE void update_phase_lfo_slot(FM_OPN *OPN, FM_SLOT *SLOT, INT32 pms, UINT32 block_fnum)
1276 {
1277 UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
1278 INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + pms + OPN->LFO_PM ];
1279
1280 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
1281 {
1282 UINT8 blk;
1283 UINT32 fn;
1284 int kc, fc;
1285
1286 block_fnum = block_fnum*2 + lfo_fn_table_index_offset;
1287
1288 blk = (block_fnum&0x7000) >> 12;
1289 fn = block_fnum & 0xfff;
1290
1291 /* keyscale code */
1292 kc = (blk<<2) | opn_fktable[fn >> 8];
1293
1294 /* phase increment counter */
1295 fc = (OPN->fn_table[fn]>>(7-blk)) + SLOT->DT[kc];
1296
1297 /* detects frequency overflow (credits to Nemesis) */
1298 if (fc < 0) fc += OPN->fn_max;
1299
1300 /* update phase */
1301 SLOT->phase += (fc * SLOT->mul) >> 1;
1302 }
1303 else /* LFO phase modulation = zero */
1304 {
1305 SLOT->phase += SLOT->Incr;
1306 }
1307 }
1308
update_phase_lfo_channel(FM_OPN * OPN,FM_CH * CH)1309 INLINE void update_phase_lfo_channel(FM_OPN *OPN, FM_CH *CH)
1310 {
1311 UINT32 block_fnum = CH->block_fnum;
1312
1313 UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
1314 INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + OPN->LFO_PM ];
1315
1316 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
1317 {
1318 UINT8 blk;
1319 UINT32 fn;
1320 int kc, fc, finc;
1321
1322 block_fnum = block_fnum*2 + lfo_fn_table_index_offset;
1323
1324 blk = (block_fnum&0x7000) >> 12;
1325 fn = block_fnum & 0xfff;
1326
1327 /* keyscale code */
1328 kc = (blk<<2) | opn_fktable[fn >> 8];
1329
1330 /* phase increment counter */
1331 fc = (OPN->fn_table[fn]>>(7-blk));
1332
1333 /* detects frequency overflow (credits to Nemesis) */
1334 finc = fc + CH->SLOT[SLOT1].DT[kc];
1335
1336 if (finc < 0) finc += OPN->fn_max;
1337 CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1;
1338
1339 finc = fc + CH->SLOT[SLOT2].DT[kc];
1340 if (finc < 0) finc += OPN->fn_max;
1341 CH->SLOT[SLOT2].phase += (finc*CH->SLOT[SLOT2].mul) >> 1;
1342
1343 finc = fc + CH->SLOT[SLOT3].DT[kc];
1344 if (finc < 0) finc += OPN->fn_max;
1345 CH->SLOT[SLOT3].phase += (finc*CH->SLOT[SLOT3].mul) >> 1;
1346
1347 finc = fc + CH->SLOT[SLOT4].DT[kc];
1348 if (finc < 0) finc += OPN->fn_max;
1349 CH->SLOT[SLOT4].phase += (finc*CH->SLOT[SLOT4].mul) >> 1;
1350 }
1351 else /* LFO phase modulation = zero */
1352 {
1353 CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
1354 CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
1355 CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
1356 CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
1357 }
1358 }
1359
chan_calc(FM_OPN * OPN,FM_CH * CH,int chnum)1360 INLINE void chan_calc(FM_OPN *OPN, FM_CH *CH, int chnum)
1361 {
1362 unsigned int eg_out;
1363
1364 UINT32 AM = OPN->LFO_AM >> CH->ams;
1365
1366 if (CH->Muted)
1367 return;
1368
1369
1370 OPN->m2 = OPN->c1 = OPN->c2 = OPN->mem = 0;
1371
1372 *CH->mem_connect = CH->mem_value; /* restore delayed sample (MEM) value to m2 or c2 */
1373
1374 eg_out = volume_calc(&CH->SLOT[SLOT1]);
1375 {
1376 INT32 out = CH->op1_out[0] + CH->op1_out[1];
1377 CH->op1_out[0] = CH->op1_out[1];
1378
1379 if( !CH->connect1 )
1380 {
1381 /* algorithm 5 */
1382 OPN->mem = OPN->c1 = OPN->c2 = CH->op1_out[0];
1383 }
1384 else
1385 {
1386 /* other algorithms */
1387 *CH->connect1 += CH->op1_out[0];
1388 }
1389
1390 CH->op1_out[1] = 0;
1391 if( eg_out < ENV_QUIET ) /* SLOT 1 */
1392 {
1393 if (!CH->FB)
1394 out=0;
1395
1396 CH->op1_out[1] = op_calc1(CH->SLOT[SLOT1].phase, eg_out, (out<<CH->FB) );
1397 }
1398 }
1399
1400 eg_out = volume_calc(&CH->SLOT[SLOT3]);
1401 if( eg_out < ENV_QUIET ) /* SLOT 3 */
1402 *CH->connect3 += op_calc(CH->SLOT[SLOT3].phase, eg_out, OPN->m2);
1403
1404 eg_out = volume_calc(&CH->SLOT[SLOT2]);
1405 if( eg_out < ENV_QUIET ) /* SLOT 2 */
1406 *CH->connect2 += op_calc(CH->SLOT[SLOT2].phase, eg_out, OPN->c1);
1407
1408 eg_out = volume_calc(&CH->SLOT[SLOT4]);
1409 if( eg_out < ENV_QUIET ) /* SLOT 4 */
1410 *CH->connect4 += op_calc(CH->SLOT[SLOT4].phase, eg_out, OPN->c2);
1411
1412
1413 /* store current MEM */
1414 CH->mem_value = OPN->mem;
1415
1416 /* update phase counters AFTER output calculations */
1417 if(CH->pms)
1418 {
1419 /* add support for 3 slot mode */
1420 if ((OPN->ST.mode & 0xC0) && (chnum == 2))
1421 {
1422 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT1], CH->pms, OPN->SL3.block_fnum[1]);
1423 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT2], CH->pms, OPN->SL3.block_fnum[2]);
1424 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT3], CH->pms, OPN->SL3.block_fnum[0]);
1425 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT4], CH->pms, CH->block_fnum);
1426 }
1427 else update_phase_lfo_channel(OPN, CH);
1428 }
1429 else /* no LFO phase modulation */
1430 {
1431 CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
1432 CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
1433 CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
1434 CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
1435 }
1436 }
1437
1438 /* update phase increment and envelope generator */
refresh_fc_eg_slot(FM_OPN * OPN,FM_SLOT * SLOT,int fc,int kc)1439 INLINE void refresh_fc_eg_slot(FM_OPN *OPN, FM_SLOT *SLOT , int fc , int kc )
1440 {
1441 int ksr = kc >> SLOT->KSR;
1442
1443 fc += SLOT->DT[kc];
1444
1445 /* detects frequency overflow (credits to Nemesis) */
1446 if (fc < 0) fc += OPN->fn_max;
1447
1448 /* (frequency) phase increment counter */
1449 SLOT->Incr = (fc * SLOT->mul) >> 1;
1450
1451 if( SLOT->ksr != ksr )
1452 {
1453 SLOT->ksr = ksr;
1454
1455 /* calculate envelope generator rates */
1456 if ((SLOT->ar + SLOT->ksr) < 32+62)
1457 {
1458 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1459 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1460 }
1461 else
1462 {
1463 SLOT->eg_sh_ar = 0;
1464 SLOT->eg_sel_ar = 17*RATE_STEPS;
1465 }
1466
1467 SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
1468 SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
1469 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
1470
1471 SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];
1472 SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];
1473 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr];
1474 }
1475 }
1476
1477 /* update phase increment counters */
1478 /* Changed from INLINE to static to work around gcc 4.2.1 codegen bug */
refresh_fc_eg_chan(FM_OPN * OPN,FM_CH * CH)1479 static void refresh_fc_eg_chan(FM_OPN *OPN, FM_CH *CH )
1480 {
1481 if( CH->SLOT[SLOT1].Incr==-1)
1482 {
1483 int fc = CH->fc;
1484 int kc = CH->kcode;
1485 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT1] , fc , kc );
1486 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT2] , fc , kc );
1487 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT3] , fc , kc );
1488 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT4] , fc , kc );
1489 }
1490 }
1491
1492 /* initialize time tables */
init_timetables(FM_ST * ST,const UINT8 * dttable)1493 static void init_timetables( FM_ST *ST , const UINT8 *dttable )
1494 {
1495 int i,d;
1496 double rate;
1497
1498 #if 0
1499 logerror("FM.C: samplerate=%8i chip clock=%8i freqbase=%f \n",
1500 ST->rate, ST->clock, ST->freqbase );
1501 #endif
1502
1503 /* DeTune table */
1504 for (d = 0;d <= 3;d++)
1505 {
1506 for (i = 0;i <= 31;i++)
1507 {
1508 rate = ((double)dttable[d*32 + i]) * SIN_LEN * ST->freqbase * (1<<FREQ_SH) / ((double)(1<<20));
1509 ST->dt_tab[d][i] = (INT32) rate;
1510 ST->dt_tab[d+4][i] = -ST->dt_tab[d][i];
1511 #if 0
1512 logerror("FM.C: DT [%2i %2i] = %8x \n", d, i, ST->dt_tab[d][i] );
1513 #endif
1514 }
1515 }
1516
1517 }
1518
1519
reset_channels(FM_ST * ST,FM_CH * CH,int num)1520 static void reset_channels( FM_ST *ST , FM_CH *CH , int num )
1521 {
1522 int c,s;
1523
1524 ST->mode = 0; /* normal mode */
1525 ST->TA = 0;
1526 ST->TAC = 0;
1527 ST->TB = 0;
1528 ST->TBC = 0;
1529
1530 for( c = 0 ; c < num ; c++ )
1531 {
1532 //memset(&CH[c], 0x00, sizeof(FM_CH));
1533 CH[c].mem_value = 0;
1534 CH[c].op1_out[0] = 0;
1535 CH[c].op1_out[1] = 0;
1536 CH[c].fc = 0;
1537 for(s = 0 ; s < 4 ; s++ )
1538 {
1539 //memset(&CH[c].SLOT[s], 0x00, sizeof(FM_SLOT));
1540 CH[c].SLOT[s].Incr = -1;
1541 CH[c].SLOT[s].key = 0;
1542 CH[c].SLOT[s].phase = 0;
1543 CH[c].SLOT[s].ssg = 0;
1544 CH[c].SLOT[s].ssgn = 0;
1545 CH[c].SLOT[s].state= EG_OFF;
1546 CH[c].SLOT[s].volume = MAX_ATT_INDEX;
1547 CH[c].SLOT[s].vol_out= MAX_ATT_INDEX;
1548 }
1549 }
1550 }
1551
1552 /* initialize generic tables */
init_tables(void)1553 static int init_tables(void)
1554 {
1555 signed int i,x;
1556 signed int n;
1557 double o,m;
1558
1559 for (x=0; x<TL_RES_LEN; x++)
1560 {
1561 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);
1562 m = floor(m);
1563
1564 /* we never reach (1<<16) here due to the (x+1) */
1565 /* result fits within 16 bits at maximum */
1566
1567 n = (int)m; /* 16 bits here */
1568 n >>= 4; /* 12 bits here */
1569 if (n&1) /* round to nearest */
1570 n = (n>>1)+1;
1571 else
1572 n = n>>1;
1573 /* 11 bits here (rounded) */
1574 n <<= 2; /* 13 bits here (as in real chip) */
1575 tl_tab[ x*2 + 0 ] = n;
1576 tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ];
1577
1578 for (i=1; i<13; i++)
1579 {
1580 tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i;
1581 tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ];
1582 }
1583 #if 0
1584 logerror("tl %04i", x);
1585 for (i=0; i<13; i++)
1586 logerror(", [%02i] %4x", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ]);
1587 logerror("\n");
1588 #endif
1589 }
1590 /*logerror("FM.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
1591
1592
1593 for (i=0; i<SIN_LEN; i++)
1594 {
1595 /* non-standard sinus */
1596 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */
1597
1598 /* we never reach zero here due to ((i*2)+1) */
1599
1600 if (m>0.0)
1601 o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */
1602 else
1603 o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */
1604
1605 o = o / (ENV_STEP/4);
1606
1607 n = (int)(2.0*o);
1608 if (n&1) /* round to nearest */
1609 n = (n>>1)+1;
1610 else
1611 n = n>>1;
1612
1613 sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
1614 /*logerror("FM.C: sin [%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[i],tl_tab[sin_tab[i]]);*/
1615 }
1616
1617 /*logerror("FM.C: ENV_QUIET= %08x\n",ENV_QUIET );*/
1618
1619
1620 /* build LFO PM modulation table */
1621 for(i = 0; i < 8; i++) /* 8 PM depths */
1622 {
1623 UINT8 fnum;
1624 for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */
1625 {
1626 UINT8 value;
1627 UINT8 step;
1628 UINT32 offset_depth = i;
1629 UINT32 offset_fnum_bit;
1630 UINT32 bit_tmp;
1631
1632 for (step=0; step<8; step++)
1633 {
1634 value = 0;
1635 for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */
1636 {
1637 if (fnum & (1<<bit_tmp)) /* only if bit "bit_tmp" is set */
1638 {
1639 offset_fnum_bit = bit_tmp * 8;
1640 value += lfo_pm_output[offset_fnum_bit + offset_depth][step];
1641 }
1642 }
1643 lfo_pm_table[(fnum*32*8) + (i*32) + step + 0] = value;
1644 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+ 8] = value;
1645 lfo_pm_table[(fnum*32*8) + (i*32) + step +16] = -value;
1646 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+24] = -value;
1647 }
1648 #if 0
1649 logerror("LFO depth=%1x FNUM=%04x (<<4=%4x): ", i, fnum, fnum<<4);
1650 for (step=0; step<16; step++) /* dump only positive part of waveforms */
1651 logerror("%02x ", lfo_pm_table[(fnum*32*8) + (i*32) + step] );
1652 logerror("\n");
1653 #endif
1654
1655 }
1656 }
1657
1658
1659
1660 #ifdef SAVE_SAMPLE
1661 sample[0]=fopen("sampsum.pcm","wb");
1662 #endif
1663
1664 return 1;
1665
1666 }
1667
1668
1669
FMCloseTable(void)1670 static void FMCloseTable( void )
1671 {
1672 #ifdef SAVE_SAMPLE
1673 fclose(sample[0]);
1674 #endif
1675 return;
1676 }
1677
1678
1679 /* CSM Key Controll */
CSMKeyControll(UINT8 type,FM_CH * CH)1680 INLINE void CSMKeyControll(UINT8 type, FM_CH *CH)
1681 {
1682 /* all key on then off (only for operators which were OFF!) */
1683 if (!CH->SLOT[SLOT1].key)
1684 {
1685 FM_KEYON(type, CH,SLOT1);
1686 FM_KEYOFF(CH, SLOT1);
1687 }
1688 if (!CH->SLOT[SLOT2].key)
1689 {
1690 FM_KEYON(type, CH,SLOT2);
1691 FM_KEYOFF(CH, SLOT2);
1692 }
1693 if (!CH->SLOT[SLOT3].key)
1694 {
1695 FM_KEYON(type, CH,SLOT3);
1696 FM_KEYOFF(CH, SLOT3);
1697 }
1698 if (!CH->SLOT[SLOT4].key)
1699 {
1700 FM_KEYON(type, CH,SLOT4);
1701 FM_KEYOFF(CH, SLOT4);
1702 }
1703 }
1704
1705 #ifdef __STATE_H__
1706 /* FM channel save , internal state only */
FMsave_state_channel(const device_config * device,FM_CH * CH,int num_ch)1707 static void FMsave_state_channel(const device_config *device,FM_CH *CH,int num_ch)
1708 {
1709 int slot , ch;
1710
1711 for(ch=0;ch<num_ch;ch++,CH++)
1712 {
1713 /* channel */
1714 state_save_register_device_item_array(device, ch, CH->op1_out);
1715 state_save_register_device_item(device, ch, CH->fc);
1716 /* slots */
1717 for(slot=0;slot<4;slot++)
1718 {
1719 FM_SLOT *SLOT = &CH->SLOT[slot];
1720 state_save_register_device_item(device, ch * 4 + slot, SLOT->phase);
1721 state_save_register_device_item(device, ch * 4 + slot, SLOT->state);
1722 state_save_register_device_item(device, ch * 4 + slot, SLOT->volume);
1723 }
1724 }
1725 }
1726
FMsave_state_st(const device_config * device,FM_ST * ST)1727 static void FMsave_state_st(const device_config *device,FM_ST *ST)
1728 {
1729 #if FM_BUSY_FLAG_SUPPORT
1730 state_save_register_device_item(device, 0, ST->busy_expiry_time.seconds );
1731 state_save_register_device_item(device, 0, ST->busy_expiry_time.attoseconds );
1732 #endif
1733 state_save_register_device_item(device, 0, ST->address );
1734 state_save_register_device_item(device, 0, ST->irq );
1735 state_save_register_device_item(device, 0, ST->irqmask );
1736 state_save_register_device_item(device, 0, ST->status );
1737 state_save_register_device_item(device, 0, ST->mode );
1738 state_save_register_device_item(device, 0, ST->prescaler_sel );
1739 state_save_register_device_item(device, 0, ST->fn_h );
1740 state_save_register_device_item(device, 0, ST->TA );
1741 state_save_register_device_item(device, 0, ST->TAC );
1742 state_save_register_device_item(device, 0, ST->TB );
1743 state_save_register_device_item(device, 0, ST->TBC );
1744 }
1745 #endif /* _STATE_H */
1746
1747 #if BUILD_OPN
1748
1749
1750
1751 /* prescaler set (and make time tables) */
OPNSetPres(FM_OPN * OPN,int pres,int timer_prescaler,int SSGpres)1752 static void OPNSetPres(FM_OPN *OPN, int pres, int timer_prescaler, int SSGpres)
1753 {
1754 int i;
1755
1756 /* frequency base */
1757 OPN->ST.freqbase = (OPN->ST.rate) ? ((double)OPN->ST.clock / OPN->ST.rate) / pres : 0;
1758
1759 #if 0
1760 OPN->ST.rate = (double)OPN->ST.clock / pres;
1761 OPN->ST.freqbase = 1.0;
1762 #endif
1763
1764 OPN->eg_timer_add = (1<<EG_SH) * OPN->ST.freqbase;
1765 OPN->eg_timer_overflow = ( 3 ) * (1<<EG_SH);
1766
1767
1768 /* Timer base time */
1769 OPN->ST.timer_prescaler = timer_prescaler;
1770
1771 /* SSG part prescaler set */
1772 if( SSGpres ) (*OPN->ST.SSG->set_clock)( OPN->ST.param, OPN->ST.clock * 2 / SSGpres );
1773
1774 /* make time tables */
1775 init_timetables( &OPN->ST, dt_tab );
1776
1777 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
1778 but LFO works with one more bit of a precision so we really need 4096 elements */
1779 /* calculate fnumber -> increment counter table */
1780 for(i = 0; i < 4096; i++)
1781 {
1782 /* freq table for octave 7 */
1783 /* OPN phase increment counter = 20bit */
1784 OPN->fn_table[i] = (UINT32)( (double)i * 32 * OPN->ST.freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
1785 #if 0
1786 logerror("FM.C: fn_table[%4i] = %08x (dec=%8i)\n",
1787 i, OPN->fn_table[i]>>6,OPN->fn_table[i]>>6 );
1788 #endif
1789 }
1790
1791 /* maximal frequency is required for Phase overflow calculation, register size is 17 bits (Nemesis) */
1792 OPN->fn_max = (UINT32)( (double)0x20000 * OPN->ST.freqbase * (1<<(FREQ_SH-10)) );
1793
1794 /* LFO freq. table */
1795 for(i = 0; i < 8; i++)
1796 {
1797 /* Amplitude modulation: 64 output levels (triangle waveform); 1 level lasts for one of "lfo_samples_per_step" samples */
1798 /* Phase modulation: one entry from lfo_pm_output lasts for one of 4 * "lfo_samples_per_step" samples */
1799 OPN->lfo_freq[i] = (1.0 / lfo_samples_per_step[i]) * (1<<LFO_SH) * OPN->ST.freqbase;
1800 #if 0
1801 logerror("FM.C: lfo_freq[%i] = %08x (dec=%8i)\n",
1802 i, OPN->lfo_freq[i],OPN->lfo_freq[i] );
1803 #endif
1804 }
1805 }
1806
1807
1808
1809 /* write a OPN mode register 0x20-0x2f */
OPNWriteMode(FM_OPN * OPN,int r,int v)1810 static void OPNWriteMode(FM_OPN *OPN, int r, int v)
1811 {
1812 UINT8 c;
1813 FM_CH *CH;
1814
1815 switch(r)
1816 {
1817 case 0x21: /* Test */
1818 break;
1819 case 0x22: /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */
1820 if( OPN->type & TYPE_LFOPAN )
1821 {
1822 if (v&0x08) /* LFO enabled ? */
1823 {
1824 OPN->lfo_inc = OPN->lfo_freq[v&7];
1825 }
1826 else
1827 {
1828 OPN->lfo_inc = 0;
1829 }
1830 }
1831 break;
1832 case 0x24: /* timer A High 8*/
1833 OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
1834 break;
1835 case 0x25: /* timer A Low 2*/
1836 OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
1837 break;
1838 case 0x26: /* timer B */
1839 OPN->ST.TB = v;
1840 break;
1841 case 0x27: /* mode, timer control */
1842 set_timers( &(OPN->ST),OPN->ST.param,v );
1843 break;
1844 case 0x28: /* key on / off */
1845 c = v & 0x03;
1846 if( c == 3 ) break;
1847 if( (v&0x04) && (OPN->type & TYPE_6CH) ) c+=3;
1848 CH = OPN->P_CH;
1849 CH = &CH[c];
1850 if(v&0x10) FM_KEYON(OPN->type,CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
1851 if(v&0x20) FM_KEYON(OPN->type,CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
1852 if(v&0x40) FM_KEYON(OPN->type,CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
1853 if(v&0x80) FM_KEYON(OPN->type,CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
1854 break;
1855 }
1856 }
1857
1858 /* write a OPN register (0x30-0xff) */
OPNWriteReg(FM_OPN * OPN,int r,int v)1859 static void OPNWriteReg(FM_OPN *OPN, int r, int v)
1860 {
1861 FM_CH *CH;
1862 FM_SLOT *SLOT;
1863
1864 UINT8 c = OPN_CHAN(r);
1865
1866 if (c == 3) return; /* 0xX3,0xX7,0xXB,0xXF */
1867
1868 if (r >= 0x100) c+=3;
1869
1870 CH = OPN->P_CH;
1871 CH = &CH[c];
1872
1873 SLOT = &(CH->SLOT[OPN_SLOT(r)]);
1874
1875 switch( r & 0xf0 )
1876 {
1877 case 0x30: /* DET , MUL */
1878 set_det_mul(&OPN->ST,CH,SLOT,v);
1879 break;
1880
1881 case 0x40: /* TL */
1882 set_tl(CH,SLOT,v);
1883 break;
1884
1885 case 0x50: /* KS, AR */
1886 set_ar_ksr(OPN->type,CH,SLOT,v);
1887 break;
1888
1889 case 0x60: /* bit7 = AM ENABLE, DR */
1890 set_dr(OPN->type, SLOT,v);
1891
1892 if(OPN->type & TYPE_LFOPAN) /* YM2608/2610/2610B/2612 */
1893 {
1894 SLOT->AMmask = (v&0x80) ? ~0 : 0;
1895 }
1896 break;
1897
1898 case 0x70: /* SR */
1899 set_sr(OPN->type,SLOT,v);
1900 break;
1901
1902 case 0x80: /* SL, RR */
1903 set_sl_rr(OPN->type,SLOT,v);
1904 break;
1905
1906 case 0x90: /* SSG-EG */
1907 SLOT->ssg = v&0x0f;
1908 SLOT->ssgn = (v&0x04)>>1; /* bit 1 in ssgn = attack */
1909
1910 /* SSG-EG envelope shapes :
1911
1912 E AtAlH
1913 1 0 0 0 \\\\
1914
1915 1 0 0 1 \___
1916
1917 1 0 1 0 \/\/
1918 ___
1919 1 0 1 1 \
1920
1921 1 1 0 0 ////
1922 ___
1923 1 1 0 1 /
1924
1925 1 1 1 0 /\/\
1926
1927 1 1 1 1 /___
1928
1929
1930 E = SSG-EG enable
1931
1932
1933 The shapes are generated using Attack, Decay and Sustain phases.
1934
1935 Each single character in the diagrams above represents this whole
1936 sequence:
1937
1938 - when KEY-ON = 1, normal Attack phase is generated (*without* any
1939 difference when compared to normal mode),
1940
1941 - later, when envelope level reaches minimum level (max volume),
1942 the EG switches to Decay phase (which works with bigger steps
1943 when compared to normal mode - see below),
1944
1945 - later when envelope level passes the SL level,
1946 the EG swithes to Sustain phase (which works with bigger steps
1947 when compared to normal mode - see below),
1948
1949 - finally when envelope level reaches maximum level (min volume),
1950 the EG switches to Attack phase again (depends on actual waveform).
1951
1952 Important is that when switch to Attack phase occurs, the phase counter
1953 of that operator will be zeroed-out (as in normal KEY-ON) but not always.
1954 (I havent found the rule for that - perhaps only when the output level is low)
1955
1956 The difference (when compared to normal Envelope Generator mode) is
1957 that the resolution in Decay and Sustain phases is 4 times lower;
1958 this results in only 256 steps instead of normal 1024.
1959 In other words:
1960 when SSG-EG is disabled, the step inside of the EG is one,
1961 when SSG-EG is enabled, the step is four (in Decay and Sustain phases).
1962
1963 Times between the level changes are the same in both modes.
1964
1965
1966 Important:
1967 Decay 1 Level (so called SL) is compared to actual SSG-EG output, so
1968 it is the same in both SSG and no-SSG modes, with this exception:
1969
1970 when the SSG-EG is enabled and is generating raising levels
1971 (when the EG output is inverted) the SL will be found at wrong level !!!
1972 For example, when SL=02:
1973 0 -6 = -6dB in non-inverted EG output
1974 96-6 = -90dB in inverted EG output
1975 Which means that EG compares its level to SL as usual, and that the
1976 output is simply inverted afterall.
1977
1978
1979 The Yamaha's manuals say that AR should be set to 0x1f (max speed).
1980 That is not necessary, but then EG will be generating Attack phase.
1981
1982 */
1983
1984
1985 break;
1986
1987 case 0xa0:
1988 switch( OPN_SLOT(r) )
1989 {
1990 case 0: /* 0xa0-0xa2 : FNUM1 */
1991 {
1992 UINT32 fn = (((UINT32)( (OPN->ST.fn_h)&7))<<8) + v;
1993 UINT8 blk = OPN->ST.fn_h>>3;
1994 /* keyscale code */
1995 CH->kcode = (blk<<2) | opn_fktable[fn >> 7];
1996 /* phase increment counter */
1997 CH->fc = OPN->fn_table[fn*2]>>(7-blk);
1998
1999 /* store fnum in clear form for LFO PM calculations */
2000 CH->block_fnum = (blk<<11) | fn;
2001
2002 CH->SLOT[SLOT1].Incr=-1;
2003 }
2004 break;
2005 case 1: /* 0xa4-0xa6 : FNUM2,BLK */
2006 OPN->ST.fn_h = v&0x3f;
2007 break;
2008 case 2: /* 0xa8-0xaa : 3CH FNUM1 */
2009 if(r < 0x100)
2010 {
2011 UINT32 fn = (((UINT32)(OPN->SL3.fn_h&7))<<8) + v;
2012 UINT8 blk = OPN->SL3.fn_h>>3;
2013 /* keyscale code */
2014 OPN->SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];
2015 /* phase increment counter */
2016 OPN->SL3.fc[c] = OPN->fn_table[fn*2]>>(7-blk);
2017 OPN->SL3.block_fnum[c] = (blk<<11) | fn;
2018 (OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
2019 }
2020 break;
2021 case 3: /* 0xac-0xae : 3CH FNUM2,BLK */
2022 if(r < 0x100)
2023 OPN->SL3.fn_h = v&0x3f;
2024 break;
2025 }
2026 break;
2027
2028 case 0xb0:
2029 switch( OPN_SLOT(r) )
2030 {
2031 case 0: /* 0xb0-0xb2 : FB,ALGO */
2032 {
2033 int feedback = (v>>3)&7;
2034 CH->ALGO = v&7;
2035 CH->FB = feedback ? feedback+6 : 0;
2036 setup_connection( OPN, CH, c );
2037 }
2038 break;
2039 case 1: /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */
2040 if( OPN->type & TYPE_LFOPAN)
2041 {
2042 /* b0-2 PMS */
2043 CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */
2044
2045 /* b4-5 AMS */
2046 CH->ams = lfo_ams_depth_shift[(v>>4) & 0x03];
2047
2048 /* PAN : b7 = L, b6 = R */
2049 OPN->pan[ c*2 ] = (v & 0x80) ? ~0 : 0;
2050 OPN->pan[ c*2+1 ] = (v & 0x40) ? ~0 : 0;
2051
2052 }
2053 break;
2054 }
2055 break;
2056 }
2057 }
2058
2059 #endif /* BUILD_OPN */
2060
2061 #if BUILD_OPN_PRESCALER
2062 /*
2063 prescaler circuit (best guess to verified chip behaviour)
2064
2065 +--------------+ +-sel2-+
2066 | +--|in20 |
2067 +---+ | +-sel1-+ | |
2068 M-CLK -+-|1/2|-+--|in10 | +---+ | out|--INT_CLOCK
2069 | +---+ | out|-|1/3|-|in21 |
2070 +----------|in11 | +---+ +------+
2071 +------+
2072
2073 reg.2d : sel2 = in21 (select sel2)
2074 reg.2e : sel1 = in11 (select sel1)
2075 reg.2f : sel1 = in10 , sel2 = in20 (clear selector)
2076 reset : sel1 = in11 , sel2 = in21 (clear both)
2077
2078 */
OPNPrescaler_w(FM_OPN * OPN,int addr,int pre_divider)2079 static void OPNPrescaler_w(FM_OPN *OPN , int addr, int pre_divider)
2080 {
2081 static const int opn_pres[4] = { 2*12 , 2*12 , 6*12 , 3*12 };
2082 static const int ssg_pres[4] = { 1 , 1 , 4 , 2 };
2083 int sel;
2084
2085 switch(addr)
2086 {
2087 case 0: /* when reset */
2088 OPN->ST.prescaler_sel = 2;
2089 break;
2090 case 1: /* when postload */
2091 break;
2092 case 0x2d: /* divider sel : select 1/1 for 1/3line */
2093 OPN->ST.prescaler_sel |= 0x02;
2094 break;
2095 case 0x2e: /* divider sel , select 1/3line for output */
2096 OPN->ST.prescaler_sel |= 0x01;
2097 break;
2098 case 0x2f: /* divider sel , clear both selector to 1/2,1/2 */
2099 OPN->ST.prescaler_sel = 0;
2100 break;
2101 }
2102 sel = OPN->ST.prescaler_sel & 3;
2103 /* update prescaler */
2104 OPNSetPres( OPN, opn_pres[sel]*pre_divider,
2105 opn_pres[sel]*pre_divider,
2106 ssg_pres[sel]*pre_divider );
2107 }
2108 #endif /* BUILD_OPN_PRESCALER */
2109
2110 #if BUILD_YM2203
2111 /*****************************************************************************/
2112 /* YM2203 local section */
2113 /*****************************************************************************/
2114
2115 /* here's the virtual YM2203(OPN) */
2116 typedef struct
2117 {
2118 UINT8 REGS[256]; /* registers */
2119 FM_OPN OPN; /* OPN state */
2120 FM_CH CH[3]; /* channel state */
2121 } YM2203;
2122
2123 /* Generate samples for one of the YM2203s */
ym2203_update_one(void * chip,FMSAMPLE ** buffer,int length)2124 void ym2203_update_one(void *chip, FMSAMPLE **buffer, int length)
2125 {
2126 YM2203 *F2203 = (YM2203 *)chip;
2127 FM_OPN *OPN = &F2203->OPN;
2128 int i;
2129 FMSAMPLE *bufL = buffer[0];
2130 FMSAMPLE *bufR = buffer[1];
2131 FM_CH *cch[3];
2132
2133 cch[0] = &F2203->CH[0];
2134 cch[1] = &F2203->CH[1];
2135 cch[2] = &F2203->CH[2];
2136
2137
2138 /* refresh PG and EG */
2139 refresh_fc_eg_chan( OPN, cch[0] );
2140 refresh_fc_eg_chan( OPN, cch[1] );
2141 if( (F2203->OPN.ST.mode & 0xc0) )
2142 {
2143 /* 3SLOT MODE */
2144 if( cch[2]->SLOT[SLOT1].Incr==-1)
2145 {
2146 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2147 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2148 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2149 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2150 }
2151 }
2152 else
2153 refresh_fc_eg_chan( OPN, cch[2] );
2154
2155
2156 /* YM2203 doesn't have LFO so we must keep these globals at 0 level */
2157 OPN->LFO_AM = 0;
2158 OPN->LFO_PM = 0;
2159
2160 /* buffering */
2161 for (i=0; i < length ; i++)
2162 {
2163 /* clear outputs */
2164 OPN->out_fm[0] = 0;
2165 OPN->out_fm[1] = 0;
2166 OPN->out_fm[2] = 0;
2167
2168 /* advance envelope generator */
2169 OPN->eg_timer += OPN->eg_timer_add;
2170 while (OPN->eg_timer >= OPN->eg_timer_overflow)
2171 {
2172 OPN->eg_timer -= OPN->eg_timer_overflow;
2173 OPN->eg_cnt++;
2174
2175 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
2176 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
2177 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
2178 }
2179
2180 /* calculate FM */
2181 chan_calc(OPN, cch[0], 0 );
2182 chan_calc(OPN, cch[1], 1 );
2183 chan_calc(OPN, cch[2], 2 );
2184
2185 /* buffering */
2186 {
2187 int lt;
2188
2189 lt = OPN->out_fm[0] + OPN->out_fm[1] + OPN->out_fm[2];
2190
2191 lt >>= FINAL_SH;
2192
2193 //Limit( lt , MAXOUT, MINOUT );
2194
2195 #ifdef SAVE_SAMPLE
2196 SAVE_ALL_CHANNELS
2197 #endif
2198
2199 /* buffering */
2200 bufL[i] = lt;
2201 bufR[i] = lt;
2202 }
2203
2204 /* timer A control */
2205 INTERNAL_TIMER_A( &F2203->OPN.ST , cch[2] )
2206 }
2207 INTERNAL_TIMER_B(&F2203->OPN.ST,length)
2208 }
2209
2210 /* ---------- reset one of chip ---------- */
ym2203_reset_chip(void * chip)2211 void ym2203_reset_chip(void *chip)
2212 {
2213 int i;
2214 YM2203 *F2203 = (YM2203 *)chip;
2215 FM_OPN *OPN = &F2203->OPN;
2216
2217 /* Reset Prescaler */
2218 OPNPrescaler_w(OPN, 0 , 1 );
2219 /* reset SSG section */
2220 (*OPN->ST.SSG->reset)(OPN->ST.param);
2221 /* status clear */
2222 FM_IRQMASK_SET(&OPN->ST,0x03);
2223 FM_BUSY_CLEAR(&OPN->ST);
2224 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2225
2226 OPN->eg_timer = 0;
2227 OPN->eg_cnt = 0;
2228
2229 FM_STATUS_RESET(&OPN->ST, 0xff);
2230
2231 reset_channels( &OPN->ST , F2203->CH , 3 );
2232 /* reset OPerator paramater */
2233 for(i = 0xb2 ; i >= 0x30 ; i-- ) OPNWriteReg(OPN,i,0);
2234 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2235 }
2236
2237 #ifdef __STATE_H__
ym2203_postload(void * chip)2238 void ym2203_postload(void *chip)
2239 {
2240 if (chip)
2241 {
2242 YM2203 *F2203 = (YM2203 *)chip;
2243 int r;
2244
2245 /* prescaler */
2246 OPNPrescaler_w(&F2203->OPN,1,1);
2247
2248 /* SSG registers */
2249 for(r=0;r<16;r++)
2250 {
2251 (*F2203->OPN.ST.SSG->write)(F2203->OPN.ST.param,0,r);
2252 (*F2203->OPN.ST.SSG->write)(F2203->OPN.ST.param,1,F2203->REGS[r]);
2253 }
2254
2255 /* OPN registers */
2256 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
2257 for(r=0x30;r<0x9e;r++)
2258 if((r&3) != 3)
2259 OPNWriteReg(&F2203->OPN,r,F2203->REGS[r]);
2260 /* FB / CONNECT , L / R / AMS / PMS */
2261 for(r=0xb0;r<0xb6;r++)
2262 if((r&3) != 3)
2263 OPNWriteReg(&F2203->OPN,r,F2203->REGS[r]);
2264
2265 /* channels */
2266 /*FM_channel_postload(F2203->CH,3);*/
2267 }
2268 }
2269
YM2203_save_state(YM2203 * F2203,const device_config * device)2270 static void YM2203_save_state(YM2203 *F2203, const device_config *device)
2271 {
2272 state_save_register_device_item_array(device, 0, F2203->REGS);
2273 FMsave_state_st(device,&F2203->OPN.ST);
2274 FMsave_state_channel(device,F2203->CH,3);
2275 /* 3slots */
2276 state_save_register_device_item_array (device, 0, F2203->OPN.SL3.fc);
2277 state_save_register_device_item (device, 0, F2203->OPN.SL3.fn_h);
2278 state_save_register_device_item_array (device, 0, F2203->OPN.SL3.kcode);
2279 }
2280 #endif /* _STATE_H */
2281
2282 /* ---------- Initialize YM2203 emulator(s) ----------
2283 'num' is the number of virtual YM2203s to allocate
2284 'clock' is the chip clock in Hz
2285 'rate' is sampling rate
2286 */
2287 //void * ym2203_init(void *param, const device_config *device, int clock, int rate,
2288 // FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg)
ym2203_init(void * param,int clock,int rate,FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler,const ssg_callbacks * ssg)2289 void * ym2203_init(void *param, int clock, int rate,
2290 FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg)
2291 {
2292 YM2203 *F2203;
2293
2294 /* allocate ym2203 state space */
2295 if( (F2203 = (YM2203 *)malloc(sizeof(YM2203)))==NULL)
2296 return NULL;
2297 /* clear */
2298 memset(F2203,0,sizeof(YM2203));
2299
2300 if( !init_tables() )
2301 {
2302 free( F2203 );
2303 return NULL;
2304 }
2305
2306 F2203->OPN.ST.param = param;
2307 F2203->OPN.type = TYPE_YM2203;
2308 F2203->OPN.P_CH = F2203->CH;
2309 //F2203->OPN.ST.device = device;
2310 F2203->OPN.ST.clock = clock;
2311 F2203->OPN.ST.rate = rate;
2312
2313 F2203->OPN.ST.timer_handler = timer_handler;
2314 F2203->OPN.ST.IRQ_Handler = IRQHandler;
2315 F2203->OPN.ST.SSG = ssg;
2316
2317 #ifdef __STATE_H__
2318 YM2203_save_state(F2203, device);
2319 #endif
2320 return F2203;
2321 }
2322
2323 /* shut down emulator */
ym2203_shutdown(void * chip)2324 void ym2203_shutdown(void *chip)
2325 {
2326 YM2203 *FM2203 = (YM2203 *)chip;
2327
2328 FMCloseTable();
2329 free(FM2203);
2330 }
2331
2332 /* YM2203 I/O interface */
ym2203_write(void * chip,int a,UINT8 v)2333 int ym2203_write(void *chip,int a,UINT8 v)
2334 {
2335 YM2203 *F2203 = (YM2203 *)chip;
2336 FM_OPN *OPN = &F2203->OPN;
2337
2338 if( !(a&1) )
2339 { /* address port */
2340 OPN->ST.address = (v &= 0xff);
2341
2342 /* Write register to SSG emulator */
2343 if( v < 16 ) (*OPN->ST.SSG->write)(OPN->ST.param,0,v);
2344
2345 /* prescaler select : 2d,2e,2f */
2346 if( v >= 0x2d && v <= 0x2f )
2347 OPNPrescaler_w(OPN , v , 1);
2348 }
2349 else
2350 { /* data port */
2351 int addr = OPN->ST.address;
2352 F2203->REGS[addr] = v;
2353 switch( addr & 0xf0 )
2354 {
2355 case 0x00: /* 0x00-0x0f : SSG section */
2356 /* Write data to SSG emulator */
2357 (*OPN->ST.SSG->write)(OPN->ST.param,a,v);
2358 break;
2359 case 0x20: /* 0x20-0x2f : Mode section */
2360 ym2203_update_req(OPN->ST.param);
2361 /* write register */
2362 OPNWriteMode(OPN,addr,v);
2363 break;
2364 default: /* 0x30-0xff : OPN section */
2365 ym2203_update_req(OPN->ST.param);
2366 /* write register */
2367 OPNWriteReg(OPN,addr,v);
2368 }
2369 FM_BUSY_SET(&OPN->ST,1);
2370 }
2371 return OPN->ST.irq;
2372 }
2373
ym2203_read(void * chip,int a)2374 UINT8 ym2203_read(void *chip,int a)
2375 {
2376 YM2203 *F2203 = (YM2203 *)chip;
2377 int addr = F2203->OPN.ST.address;
2378 UINT8 ret = 0;
2379
2380 if( !(a&1) )
2381 { /* status port */
2382 ret = FM_STATUS_FLAG(&F2203->OPN.ST);
2383 }
2384 else
2385 { /* data port (only SSG) */
2386 if( addr < 16 ) ret = (*F2203->OPN.ST.SSG->read)(F2203->OPN.ST.param);
2387 }
2388 return ret;
2389 }
2390
ym2203_timer_over(void * chip,int c)2391 int ym2203_timer_over(void *chip,int c)
2392 {
2393 YM2203 *F2203 = (YM2203 *)chip;
2394
2395 if( c )
2396 { /* Timer B */
2397 TimerBOver( &(F2203->OPN.ST) );
2398 }
2399 else
2400 { /* Timer A */
2401 ym2203_update_req(F2203->OPN.ST.param);
2402 /* timer update */
2403 TimerAOver( &(F2203->OPN.ST) );
2404 /* CSM mode key,TL control */
2405 if( F2203->OPN.ST.mode & 0x80 )
2406 { /* CSM mode auto key on */
2407 CSMKeyControll( F2203->OPN.type, &(F2203->CH[2]) );
2408 }
2409 }
2410 return F2203->OPN.ST.irq;
2411 }
2412
ym2203_set_mutemask(void * chip,UINT32 MuteMask)2413 void ym2203_set_mutemask(void *chip, UINT32 MuteMask)
2414 {
2415 YM2203 *F2203 = (YM2203 *)chip;
2416 UINT8 CurChn;
2417
2418 for (CurChn = 0; CurChn < 3; CurChn ++)
2419 F2203->CH[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
2420
2421 return;
2422 }
2423 #endif /* BUILD_YM2203 */
2424
2425
2426
2427 #if (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
2428
2429 /* ADPCM type A channel struct */
2430 typedef struct
2431 {
2432 UINT8 flag; /* port state */
2433 UINT8 flagMask; /* arrived flag mask */
2434 UINT8 now_data; /* current ROM data */
2435 UINT32 now_addr; /* current ROM address */
2436 UINT32 now_step;
2437 UINT32 step;
2438 UINT32 start; /* sample data start address*/
2439 UINT32 end; /* sample data end address */
2440 UINT8 IL; /* Instrument Level */
2441 INT32 adpcm_acc; /* accumulator */
2442 INT32 adpcm_step; /* step */
2443 INT32 adpcm_out; /* (speedup) hiro-shi!! */
2444 INT8 vol_mul; /* volume in "0.75dB" steps */
2445 UINT8 vol_shift; /* volume in "-6dB" steps */
2446 INT32 *pan; /* &out_adpcm[OPN_xxxx] */
2447 UINT8 Muted;
2448 } ADPCM_CH;
2449
2450 /* here's the virtual YM2610 */
2451 typedef struct
2452 {
2453 UINT8 REGS[512]; /* registers */
2454 FM_OPN OPN; /* OPN state */
2455 FM_CH CH[6]; /* channel state */
2456 UINT8 addr_A1; /* address line A1 */
2457
2458 /* ADPCM-A unit */
2459 //const UINT8 *pcmbuf; /* pcm rom buffer */
2460 UINT8 *pcmbuf; /* pcm rom buffer */
2461 UINT32 pcm_size; /* size of pcm rom */
2462 UINT8 adpcmTL; /* adpcmA total level */
2463 ADPCM_CH adpcm[6]; /* adpcm channels */
2464 UINT32 adpcmreg[0x30]; /* registers */
2465 UINT8 adpcm_arrivedEndAddress;
2466 YM_DELTAT deltaT; /* Delta-T ADPCM unit */
2467 UINT8 MuteDeltaT;
2468
2469 UINT8 flagmask; /* YM2608 only */
2470 UINT8 irqmask; /* YM2608 only */
2471 } YM2610;
2472
2473 /* here is the virtual YM2608 */
2474 typedef YM2610 YM2608;
2475
2476
2477 /**** YM2610 ADPCM defines ****/
2478 #define ADPCM_SHIFT (16) /* frequency step rate */
2479 #define ADPCMA_ADDRESS_SHIFT 8 /* adpcm A address shift */
2480
2481 /* Algorithm and tables verified on real YM2608 and YM2610 */
2482
2483 /* usual ADPCM table (16 * 1.1^N) */
2484 static const int steps[49] =
2485 {
2486 16, 17, 19, 21, 23, 25, 28,
2487 31, 34, 37, 41, 45, 50, 55,
2488 60, 66, 73, 80, 88, 97, 107,
2489 118, 130, 143, 157, 173, 190, 209,
2490 230, 253, 279, 307, 337, 371, 408,
2491 449, 494, 544, 598, 658, 724, 796,
2492 876, 963, 1060, 1166, 1282, 1411, 1552
2493 };
2494
2495 /* different from the usual ADPCM table */
2496 static const int step_inc[8] = { -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16 };
2497
2498 /* speedup purposes only */
2499 static int jedi_table[ 49*16 ];
2500
2501
Init_ADPCMATable(void)2502 static void Init_ADPCMATable(void)
2503 {
2504 int step, nib;
2505
2506 for (step = 0; step < 49; step++)
2507 {
2508 /* loop over all nibbles and compute the difference */
2509 for (nib = 0; nib < 16; nib++)
2510 {
2511 int value = (2*(nib & 0x07) + 1) * steps[step] / 8;
2512 jedi_table[step*16 + nib] = (nib&0x08) ? -value : value;
2513 }
2514 }
2515 }
2516
2517 /* ADPCM A (Non control type) : calculate one channel output */
ADPCMA_calc_chan(YM2610 * F2610,ADPCM_CH * ch)2518 INLINE void ADPCMA_calc_chan( YM2610 *F2610, ADPCM_CH *ch )
2519 {
2520 UINT32 step;
2521 UINT8 data;
2522
2523 if (ch->Muted)
2524 return;
2525
2526
2527 ch->now_step += ch->step;
2528 if ( ch->now_step >= (1<<ADPCM_SHIFT) )
2529 {
2530 step = ch->now_step >> ADPCM_SHIFT;
2531 ch->now_step &= (1<<ADPCM_SHIFT)-1;
2532 do{
2533 /* end check */
2534 /* 11-06-2001 JB: corrected comparison. Was > instead of == */
2535 /* YM2610 checks lower 20 bits only, the 4 MSB bits are sample bank */
2536 /* Here we use 1<<21 to compensate for nibble calculations */
2537
2538 if ( (ch->now_addr & ((1<<21)-1)) == ((ch->end<<1) & ((1<<21)-1)) )
2539 {
2540 ch->flag = 0;
2541 F2610->adpcm_arrivedEndAddress |= ch->flagMask;
2542 return;
2543 }
2544 #if 0
2545 if ( ch->now_addr > (F2610->pcmsizeA<<1) )
2546 {
2547 #ifdef _DEBUG
2548 LOG(LOG_WAR,("YM2610: Attempting to play past adpcm rom size!\n" ));
2549 #endif
2550 return;
2551 }
2552 #endif
2553 if ( ch->now_addr&1 )
2554 data = ch->now_data & 0x0f;
2555 else
2556 {
2557 ch->now_data = *(F2610->pcmbuf+(ch->now_addr>>1));
2558 data = (ch->now_data >> 4) & 0x0f;
2559 }
2560
2561 ch->now_addr++;
2562
2563 ch->adpcm_acc += jedi_table[ch->adpcm_step + data];
2564
2565 /* extend 12-bit signed int */
2566 if (ch->adpcm_acc & ~0x7ff)
2567 ch->adpcm_acc |= ~0xfff;
2568 else
2569 ch->adpcm_acc &= 0xfff;
2570
2571 ch->adpcm_step += step_inc[data & 7];
2572 Limit( ch->adpcm_step, 48*16, 0*16 );
2573
2574 }while(--step);
2575
2576 /* calc pcm * volume data */
2577 ch->adpcm_out = ((ch->adpcm_acc * ch->vol_mul) >> ch->vol_shift) & ~3; /* multiply, shift and mask out 2 LSB bits */
2578 }
2579
2580 /* output for work of output channels (out_adpcm[OPNxxxx])*/
2581 *(ch->pan) += ch->adpcm_out;
2582 }
2583
2584 /* ADPCM type A Write */
FM_ADPCMAWrite(YM2610 * F2610,int r,int v)2585 static void FM_ADPCMAWrite(YM2610 *F2610,int r,int v)
2586 {
2587 ADPCM_CH *adpcm = F2610->adpcm;
2588 UINT8 c = r&0x07;
2589
2590 F2610->adpcmreg[r] = v&0xff; /* stock data */
2591 switch( r )
2592 {
2593 case 0x00: /* DM,--,C5,C4,C3,C2,C1,C0 */
2594 if( !(v&0x80) )
2595 {
2596 /* KEY ON */
2597 for( c = 0; c < 6; c++ )
2598 {
2599 if( (v>>c)&1 )
2600 {
2601 /**** start adpcm ****/
2602 // The .step variable is already set and for the YM2608 it is different on channels 4 and 5.
2603 //adpcm[c].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/3.0);
2604 adpcm[c].now_addr = adpcm[c].start<<1;
2605 adpcm[c].now_step = 0;
2606 adpcm[c].adpcm_acc = 0;
2607 adpcm[c].adpcm_step= 0;
2608 adpcm[c].adpcm_out = 0;
2609 adpcm[c].flag = 1;
2610
2611 if(F2610->pcmbuf==NULL)
2612 { /* Check ROM Mapped */
2613 #ifdef _DEBUG
2614 logerror("YM2608-YM2610: ADPCM-A rom not mapped\n");
2615 #endif
2616 adpcm[c].flag = 0;
2617 }
2618 else
2619 {
2620 if(adpcm[c].end >= F2610->pcm_size)
2621 { /* Check End in Range */
2622 #ifdef _DEBUG
2623 logerror("YM2610: ADPCM-A end out of range: $%08x\n",adpcm[c].end);
2624 #endif
2625 /*adpcm[c].end = F2610->pcm_size-1;*/ /* JB: DO NOT uncomment this, otherwise you will break the comparison in the ADPCM_CALC_CHA() */
2626 }
2627 if(adpcm[c].start >= F2610->pcm_size) /* Check Start in Range */
2628 {
2629 #ifdef _DEBUG
2630 logerror("YM2608-YM2610: ADPCM-A start out of range: $%08x\n",adpcm[c].start);
2631 #endif
2632 adpcm[c].flag = 0;
2633 }
2634 }
2635 }
2636 }
2637 }
2638 else
2639 {
2640 /* KEY OFF */
2641 for( c = 0; c < 6; c++ )
2642 if( (v>>c)&1 )
2643 adpcm[c].flag = 0;
2644 }
2645 break;
2646 case 0x01: /* B0-5 = TL */
2647 F2610->adpcmTL = (v & 0x3f) ^ 0x3f;
2648 for( c = 0; c < 6; c++ )
2649 {
2650 int volume = F2610->adpcmTL + adpcm[c].IL;
2651
2652 if ( volume >= 63 ) /* This is correct, 63 = quiet */
2653 {
2654 adpcm[c].vol_mul = 0;
2655 adpcm[c].vol_shift = 0;
2656 }
2657 else
2658 {
2659 adpcm[c].vol_mul = 15 - (volume & 7); /* so called 0.75 dB */
2660 adpcm[c].vol_shift = 1 + (volume >> 3); /* Yamaha engineers used the approximation: each -6 dB is close to divide by two (shift right) */
2661 }
2662
2663 /* calc pcm * volume data */
2664 adpcm[c].adpcm_out = ((adpcm[c].adpcm_acc * adpcm[c].vol_mul) >> adpcm[c].vol_shift) & ~3; /* multiply, shift and mask out low 2 bits */
2665 }
2666 break;
2667 default:
2668 c = r&0x07;
2669 if( c >= 0x06 ) return;
2670 switch( r&0x38 )
2671 {
2672 case 0x08: /* B7=L,B6=R, B4-0=IL */
2673 {
2674 int volume;
2675
2676 adpcm[c].IL = (v & 0x1f) ^ 0x1f;
2677
2678 volume = F2610->adpcmTL + adpcm[c].IL;
2679
2680 if ( volume >= 63 ) /* This is correct, 63 = quiet */
2681 {
2682 adpcm[c].vol_mul = 0;
2683 adpcm[c].vol_shift = 0;
2684 }
2685 else
2686 {
2687 adpcm[c].vol_mul = 15 - (volume & 7); /* so called 0.75 dB */
2688 adpcm[c].vol_shift = 1 + (volume >> 3); /* Yamaha engineers used the approximation: each -6 dB is close to divide by two (shift right) */
2689 }
2690
2691 adpcm[c].pan = &F2610->OPN.out_adpcm[(v>>6)&0x03];
2692
2693 /* calc pcm * volume data */
2694 adpcm[c].adpcm_out = ((adpcm[c].adpcm_acc * adpcm[c].vol_mul) >> adpcm[c].vol_shift) & ~3; /* multiply, shift and mask out low 2 bits */
2695 }
2696 break;
2697 case 0x10:
2698 case 0x18:
2699 adpcm[c].start = ( (F2610->adpcmreg[0x18 + c]*0x0100 | F2610->adpcmreg[0x10 + c]) << ADPCMA_ADDRESS_SHIFT);
2700 break;
2701 case 0x20:
2702 case 0x28:
2703 adpcm[c].end = ( (F2610->adpcmreg[0x28 + c]*0x0100 | F2610->adpcmreg[0x20 + c]) << ADPCMA_ADDRESS_SHIFT);
2704 adpcm[c].end += (1<<ADPCMA_ADDRESS_SHIFT) - 1;
2705 break;
2706 }
2707 }
2708 }
2709
2710 #ifdef __STATE_H__
2711 /* FM channel save , internal state only */
FMsave_state_adpcma(const device_config * device,ADPCM_CH * adpcm)2712 static void FMsave_state_adpcma(const device_config *device,ADPCM_CH *adpcm)
2713 {
2714 int ch;
2715
2716 for(ch=0;ch<6;ch++,adpcm++)
2717 {
2718 state_save_register_device_item(device, ch, adpcm->flag);
2719 state_save_register_device_item(device, ch, adpcm->now_data);
2720 state_save_register_device_item(device, ch, adpcm->now_addr);
2721 state_save_register_device_item(device, ch, adpcm->now_step);
2722 state_save_register_device_item(device, ch, adpcm->adpcm_acc);
2723 state_save_register_device_item(device, ch, adpcm->adpcm_step);
2724 state_save_register_device_item(device, ch, adpcm->adpcm_out);
2725 }
2726 }
2727 #endif /* _STATE_H */
2728
2729 #endif /* (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B) */
2730
2731
2732 #if BUILD_YM2608
2733 /*****************************************************************************/
2734 /* YM2608 local section */
2735 /*****************************************************************************/
2736
2737
2738
2739 static const unsigned int YM2608_ADPCM_ROM_addr[2*6] = {
2740 0x0000, 0x01bf, /* bass drum */
2741 0x01c0, 0x043f, /* snare drum */
2742 0x0440, 0x1b7f, /* top cymbal */
2743 0x1b80, 0x1cff, /* high hat */
2744 0x1d00, 0x1f7f, /* tom tom */
2745 0x1f80, 0x1fff /* rim shot */
2746 };
2747
2748
2749 /*
2750 This data is derived from the chip's output - internal ROM can't be read.
2751 It was verified, using real YM2608, that this ADPCM stream produces 100% correct output signal.
2752 */
2753
2754 static const unsigned char YM2608_ADPCM_ROM[0x2000] = {
2755
2756 /* Source: 01BD.ROM */
2757 /* Length: 448 / 0x000001C0 */
2758
2759 0x88,0x08,0x08,0x08,0x00,0x88,0x16,0x76,0x99,0xB8,0x22,0x3A,0x84,0x3C,0xB1,0x54,
2760 0x10,0xA9,0x98,0x32,0x80,0x33,0x9A,0xA7,0x4A,0xB4,0x58,0xBC,0x15,0x29,0x8A,0x97,
2761 0x9B,0x44,0xAC,0x80,0x12,0xDE,0x13,0x1B,0xC0,0x58,0xC8,0x11,0x0A,0xA2,0x1A,0xA0,
2762 0x00,0x98,0x0B,0x93,0x9E,0x92,0x0A,0x88,0xBE,0x14,0x1B,0x98,0x08,0xA1,0x4A,0xC1,
2763 0x30,0xD9,0x33,0x98,0x10,0x89,0x17,0x1A,0x82,0x29,0x37,0x0C,0x83,0x50,0x9A,0x24,
2764 0x1A,0x83,0x10,0x23,0x19,0xB3,0x72,0x8A,0x16,0x10,0x0A,0x93,0x70,0x99,0x23,0x99,
2765 0x02,0x20,0x91,0x18,0x02,0x41,0xAB,0x24,0x18,0x81,0x99,0x4A,0xE8,0x28,0x9A,0x99,
2766 0xA1,0x2F,0xA8,0x9D,0x90,0x08,0xCC,0xA3,0x1D,0xCA,0x82,0x0B,0xD8,0x08,0xB9,0x09,
2767 0xBC,0xB8,0x00,0xBE,0x90,0x1B,0xCA,0x00,0x9B,0x8A,0xA8,0x91,0x0F,0xB3,0x3D,0xB8,
2768 0x31,0x0B,0xA5,0x0A,0x11,0xA1,0x48,0x92,0x10,0x50,0x91,0x30,0x23,0x09,0x37,0x39,
2769 0xA2,0x72,0x89,0x92,0x30,0x83,0x1C,0x96,0x28,0xB9,0x24,0x8C,0xA1,0x31,0xAD,0xA9,
2770 0x13,0x9C,0xBA,0xA8,0x0B,0xBF,0xB8,0x9B,0xCA,0x88,0xDB,0xB8,0x19,0xFC,0x92,0x0A,
2771 0xBA,0x89,0xAB,0xB8,0xAB,0xD8,0x08,0xAD,0xBA,0x33,0x9D,0xAA,0x83,0x3A,0xC0,0x40,
2772 0xB9,0x15,0x39,0xA2,0x52,0x89,0x02,0x63,0x88,0x13,0x23,0x03,0x52,0x02,0x54,0x00,
2773 0x11,0x23,0x23,0x35,0x20,0x01,0x44,0x41,0x80,0x24,0x40,0xA9,0x45,0x19,0x81,0x12,
2774 0x81,0x02,0x11,0x21,0x19,0x02,0x61,0x8A,0x13,0x3A,0x10,0x12,0x23,0x8B,0x37,0x18,
2775 0x91,0x24,0x10,0x81,0x34,0x20,0x05,0x32,0x82,0x53,0x20,0x14,0x33,0x31,0x34,0x52,
2776 0x00,0x43,0x32,0x13,0x52,0x22,0x13,0x52,0x11,0x43,0x11,0x32,0x32,0x32,0x22,0x02,
2777 0x13,0x12,0x89,0x22,0x19,0x81,0x81,0x08,0xA8,0x08,0x8B,0x90,0x1B,0xBA,0x8A,0x9B,
2778 0xB9,0x89,0xCA,0xB9,0xAB,0xCA,0x9B,0xCA,0xB9,0xAB,0xDA,0x99,0xAC,0xBB,0x9B,0xAC,
2779 0xAA,0xBA,0xAC,0xAB,0x9A,0xAA,0xAA,0xBA,0xB8,0xA9,0xBA,0x99,0xA9,0x9A,0xA0,0x8A,
2780 0xA9,0x08,0x8A,0xA9,0x00,0x99,0x89,0x88,0x98,0x08,0x99,0x00,0x89,0x80,0x08,0x98,
2781 0x00,0x88,0x88,0x80,0x90,0x80,0x90,0x80,0x81,0x99,0x08,0x88,0x99,0x09,0x00,0x1A,
2782 0xA8,0x10,0x9A,0x88,0x08,0x0A,0x8A,0x89,0x99,0xA8,0x98,0xA9,0x99,0x99,0xA9,0x99,
2783 0xAA,0x8A,0xAA,0x9B,0x8A,0x9A,0xA9,0x9A,0xBA,0x99,0x9A,0xAA,0x99,0x89,0xA9,0x99,
2784 0x98,0x9A,0x98,0x88,0x09,0x89,0x09,0x08,0x08,0x09,0x18,0x18,0x00,0x12,0x00,0x11,
2785 0x11,0x11,0x12,0x12,0x21,0x21,0x22,0x22,0x22,0x22,0x22,0x22,0x32,0x31,0x32,0x31,
2786 0x32,0x32,0x21,0x31,0x21,0x32,0x21,0x12,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
2787
2788 /* Source: 02SD.ROM */
2789 /* Length: 640 / 0x00000280 */
2790
2791 0x0A,0xDC,0x14,0x0B,0xBA,0xBC,0x01,0x0F,0xF5,0x2F,0x87,0x19,0xC9,0x24,0x1B,0xA1,
2792 0x31,0x99,0x90,0x32,0x32,0xFE,0x83,0x48,0xA8,0xA9,0x23,0x19,0xBC,0x91,0x02,0x41,
2793 0xDE,0x81,0x28,0xA8,0x0A,0xB1,0x72,0xDA,0x23,0xBC,0x04,0x19,0xB8,0x21,0x8A,0x03,
2794 0x29,0xBA,0x14,0x21,0x0B,0xC0,0x43,0x08,0x91,0x50,0x93,0x0F,0x86,0x1A,0x91,0x18,
2795 0x21,0xCB,0x27,0x0A,0xA1,0x42,0x8C,0xA9,0x21,0x10,0x08,0xAB,0x94,0x2A,0xDA,0x02,
2796 0x8B,0x91,0x09,0x98,0xAE,0x80,0xA9,0x02,0x0A,0xE9,0x21,0xBB,0x15,0x20,0xBE,0x92,
2797 0x42,0x09,0xA9,0x11,0x34,0x08,0x12,0x0A,0x27,0x29,0xA1,0x52,0x12,0x8E,0x92,0x28,
2798 0x92,0x2B,0xD1,0x23,0xBF,0x81,0x10,0x99,0xA8,0x0A,0xC4,0x3B,0xB9,0xB0,0x00,0x62,
2799 0xCF,0x92,0x29,0x92,0x2B,0xB1,0x1C,0xB2,0x72,0xAA,0x88,0x11,0x18,0x80,0x13,0x9E,
2800 0x03,0x18,0xB0,0x60,0xA1,0x28,0x88,0x08,0x04,0x10,0x8F,0x96,0x19,0x90,0x01,0x09,
2801 0xC8,0x50,0x91,0x8A,0x01,0xAB,0x03,0x50,0xBA,0x9D,0x93,0x68,0xBA,0x80,0x22,0xCB,
2802 0x41,0xBC,0x92,0x60,0xB9,0x1A,0x95,0x4A,0xC8,0x20,0x88,0x33,0xAC,0x92,0x38,0x83,
2803 0x09,0x80,0x16,0x09,0x29,0xD0,0x54,0x8C,0xA2,0x28,0x91,0x89,0x93,0x60,0xCD,0x85,
2804 0x1B,0xA1,0x49,0x90,0x8A,0x80,0x34,0x0C,0xC9,0x14,0x19,0x98,0xA0,0x40,0xA9,0x21,
2805 0xD9,0x34,0x0A,0xA9,0x10,0x23,0xCB,0x25,0xAA,0x25,0x9B,0x13,0xCD,0x16,0x09,0xA0,
2806 0x80,0x01,0x19,0x90,0x88,0x21,0xAC,0x33,0x8B,0xD8,0x27,0x3B,0xB8,0x81,0x31,0x80,
2807 0xAF,0x97,0x0A,0x82,0x0A,0xA0,0x21,0x89,0x8A,0xA2,0x32,0x8D,0xBB,0x87,0x19,0x21,
2808 0xC9,0xBC,0x45,0x09,0x90,0x09,0xA1,0x24,0x1A,0xD0,0x10,0x08,0x11,0xA9,0x21,0xE8,
2809 0x60,0xA9,0x14,0x0C,0xD1,0x32,0xAB,0x04,0x0C,0x81,0x90,0x29,0x83,0x9B,0x01,0x8F,
2810 0x97,0x0B,0x82,0x18,0x88,0xBA,0x06,0x39,0xC8,0x23,0xBC,0x04,0x09,0x92,0x08,0x1A,
2811 0xBB,0x74,0x8C,0x81,0x18,0x81,0x9D,0x83,0x41,0xCD,0x81,0x40,0x9A,0x90,0x10,0x12,
2812 0x9C,0xA1,0x68,0xD8,0x33,0x9C,0x91,0x01,0x12,0xBE,0x02,0x09,0x12,0x99,0x9A,0x36,
2813 0x0A,0xB0,0x30,0x88,0xA3,0x2D,0x12,0xBC,0x03,0x3A,0x11,0xBD,0x08,0xC8,0x62,0x80,
2814 0x8B,0xD8,0x23,0x38,0xF9,0x12,0x08,0x99,0x91,0x21,0x99,0x85,0x2F,0xB2,0x30,0x90,
2815 0x88,0xD9,0x53,0xAC,0x82,0x19,0x91,0x20,0xCC,0x96,0x29,0xC9,0x24,0x89,0x80,0x99,
2816 0x12,0x08,0x18,0x88,0x99,0x23,0xAB,0x73,0xCB,0x33,0x9F,0x04,0x2B,0xB1,0x08,0x03,
2817 0x1B,0xC9,0x21,0x32,0xFA,0x33,0xDB,0x02,0x33,0xAE,0xB9,0x54,0x8B,0xA1,0x20,0x89,
2818 0x90,0x11,0x88,0x09,0x98,0x23,0xBE,0x37,0x8D,0x81,0x20,0xAA,0x34,0xBB,0x13,0x18,
2819 0xB9,0x40,0xB1,0x18,0x83,0x8E,0xB2,0x72,0xBC,0x82,0x30,0xA9,0x9A,0x24,0x8B,0x27,
2820 0x0E,0x91,0x20,0x90,0x08,0xB0,0x32,0xB9,0x21,0xB0,0xAC,0x45,0x9A,0xA1,0x50,0xA9,
2821 0x80,0x0A,0x26,0x9B,0x11,0xBB,0x23,0x71,0xCB,0x12,0x10,0xB8,0x40,0xA9,0xA5,0x39,
2822 0xC0,0x30,0xB2,0x20,0xAA,0xBA,0x76,0x1C,0xC1,0x48,0x98,0x80,0x18,0x81,0xAA,0x23,
2823 0x9C,0xA2,0x32,0xAC,0x9A,0x43,0x9C,0x12,0xAD,0x82,0x72,0xBC,0x00,0x82,0x39,0xD1,
2824 0x3A,0xB8,0x35,0x9B,0x10,0x40,0xF9,0x22,0x0A,0xC0,0x51,0xB9,0x82,0x18,0x98,0xA3,
2825 0x79,0xD0,0x20,0x88,0x09,0x01,0x99,0x82,0x11,0x38,0xFC,0x33,0x09,0xC8,0x40,0xA9,
2826 0x11,0x29,0xAA,0x94,0x3A,0xC2,0x4A,0xC0,0x89,0x52,0xBC,0x11,0x08,0x09,0xB8,0x71,
2827 0xA9,0x08,0xA8,0x62,0x8D,0x92,0x10,0x00,0x9E,0x94,0x38,0xBA,0x13,0x88,0x90,0x4A,
2828 0xE2,0x30,0xBA,0x02,0x00,0x19,0xD9,0x62,0xBB,0x04,0x0B,0xA3,0x68,0xB9,0x21,0x88,
2829 0x9D,0x04,0x10,0x8C,0xC8,0x62,0x99,0xAA,0x24,0x1A,0x80,0x9A,0x14,0x9B,0x26,0x8C,
2830 0x92,0x30,0xB9,0x09,0xA3,0x71,0xBB,0x10,0x19,0x82,0x39,0xDB,0x02,0x44,0x9F,0x10,
2831
2832 /* Source: 04TOP.ROM */
2833 /* Length: 5952 / 0x00001740 */
2834
2835 0x07,0xFF,0x7C,0x3C,0x31,0xC6,0xC4,0xBB,0x7F,0x7F,0x7B,0x82,0x8A,0x4D,0x5F,0x7C,
2836 0x3E,0x44,0xD2,0xB3,0xA0,0x19,0x1B,0x6C,0x81,0x28,0xC4,0xA1,0x1C,0x4B,0x18,0x00,
2837 0x2A,0xA2,0x0A,0x7C,0x2A,0x00,0x01,0x89,0x98,0x48,0x8A,0x3C,0x28,0x2A,0x5B,0x3E,
2838 0x3A,0x1A,0x3B,0x3D,0x4B,0x3B,0x4A,0x08,0x2A,0x1A,0x2C,0x4A,0x3B,0x82,0x99,0x3C,
2839 0x5D,0x29,0x2B,0x39,0x0B,0x23,0xAB,0x1A,0x4C,0x79,0xA3,0x01,0xC1,0x2A,0x0A,0x38,
2840 0xA7,0xB9,0x12,0x1F,0x29,0x08,0x82,0xA1,0x08,0xA9,0x42,0xAA,0x95,0xB3,0x90,0x81,
2841 0x09,0xD4,0x1A,0x80,0x1B,0x07,0xB8,0x12,0x8E,0x49,0x81,0x92,0xD3,0x90,0xA1,0x2A,
2842 0x02,0xE1,0xA3,0x99,0x02,0xB3,0x94,0xB3,0xB0,0xF4,0x98,0x93,0x90,0x13,0xE1,0x81,
2843 0x99,0x38,0x91,0xA6,0xD3,0x99,0x94,0xC1,0x83,0xB1,0x92,0x98,0x49,0xC4,0xB2,0xA4,
2844 0xA3,0xD0,0x1A,0x30,0xBA,0x59,0x02,0xD4,0xA0,0xA4,0xA2,0x8A,0x01,0x00,0xB7,0xA8,
2845 0x18,0x2A,0x2B,0x1E,0x23,0xC8,0x1A,0x00,0x39,0xA0,0x18,0x92,0x4F,0x2D,0x5A,0x10,
2846 0x89,0x81,0x2A,0x8B,0x6A,0x02,0x09,0xB3,0x8D,0x48,0x1B,0x80,0x19,0x34,0xF8,0x29,
2847 0x0A,0x7B,0x2A,0x28,0x81,0x0C,0x02,0x1E,0x29,0x09,0x12,0xC2,0x94,0xE1,0x18,0x98,
2848 0x02,0xC4,0x89,0x91,0x1A,0x20,0xA9,0x02,0x1B,0x48,0x8E,0x20,0x88,0x2D,0x08,0x59,
2849 0x1B,0x02,0xA3,0xB1,0x8A,0x1E,0x58,0x80,0xC2,0xB6,0x88,0x91,0x88,0x11,0xA1,0xA3,
2850 0xE2,0x01,0xB0,0x19,0x11,0x09,0xF4,0x88,0x09,0x88,0x19,0x89,0x12,0xF1,0x2A,0x28,
2851 0x8C,0x25,0x99,0xA4,0x98,0x39,0xA1,0x00,0xD0,0x58,0xAA,0x59,0x01,0x0C,0x00,0x2B,
2852 0x00,0x08,0x89,0x6B,0x69,0x90,0x01,0x90,0x98,0x12,0xB3,0xF3,0xA0,0x89,0x02,0x3B,
2853 0x0C,0x50,0xA9,0x4E,0x6B,0x19,0x28,0x09,0xA2,0x08,0x2F,0x20,0x88,0x92,0x8A,0x11,
2854 0xC4,0x93,0xF1,0x18,0x88,0x11,0xF2,0x80,0x92,0xA8,0x02,0xA8,0xB7,0xB3,0xA3,0xA0,
2855 0x88,0x1A,0x40,0xE2,0x91,0x19,0x88,0x18,0x91,0x83,0xC1,0xB5,0x92,0xA9,0xC6,0x90,
2856 0x01,0xC2,0x81,0x98,0x03,0xF0,0x00,0x2C,0x2A,0x92,0x2C,0x83,0x1F,0x3A,0x29,0x00,
2857 0xB8,0x70,0xAB,0x69,0x18,0x89,0x10,0x0D,0x12,0x0B,0x88,0x4A,0x3A,0x9B,0x70,0xA8,
2858 0x28,0x2F,0x2A,0x3A,0x1B,0x85,0x88,0x8B,0x6A,0x29,0x00,0x91,0x91,0x1B,0x7C,0x29,
2859 0x01,0x88,0x90,0x19,0x2B,0x2B,0x00,0x39,0xA8,0x5E,0x21,0x89,0x91,0x09,0x3A,0x6F,
2860 0x2A,0x18,0x18,0x8B,0x50,0x89,0x2B,0x19,0x49,0x88,0x29,0xF5,0x89,0x08,0x09,0x12,
2861 0xAA,0x15,0xB0,0x82,0xAC,0x38,0x00,0x3F,0x81,0x10,0xB0,0x49,0xA2,0x81,0x3A,0xC8,
2862 0x87,0x90,0xC4,0xA3,0x99,0x19,0x83,0xE1,0x84,0xE2,0xA2,0x90,0x80,0x93,0xB5,0xC4,
2863 0xB3,0xA1,0x0A,0x18,0x92,0xC4,0xA0,0x93,0x0C,0x3A,0x18,0x01,0x1E,0x20,0xB1,0x82,
2864 0x8C,0x03,0xB5,0x2E,0x82,0x19,0xB2,0x1B,0x1B,0x6B,0x4C,0x19,0x12,0x8B,0x5A,0x11,
2865 0x0C,0x3A,0x2C,0x18,0x3D,0x08,0x2A,0x5C,0x18,0x00,0x88,0x3D,0x29,0x80,0x2A,0x09,
2866 0x00,0x7A,0x0A,0x10,0x0B,0x69,0x98,0x10,0x81,0x3F,0x00,0x18,0x19,0x91,0xB7,0x9A,
2867 0x28,0x8A,0x48,0x92,0xF3,0xA2,0x88,0x98,0x87,0xA1,0x88,0x80,0x81,0x95,0xD1,0xA3,
2868 0x1B,0x1C,0x39,0x10,0xA1,0x2A,0x0B,0x7A,0x4B,0x80,0x13,0xC1,0xD1,0x2B,0x2A,0x85,
2869 0xB2,0xA2,0x93,0xB2,0xD3,0x80,0xD1,0x18,0x08,0x08,0xB7,0x98,0x81,0x3F,0x01,0x88,
2870 0x01,0xE2,0x00,0x9A,0x59,0x08,0x10,0xC3,0x99,0x84,0xA9,0xA5,0x91,0x91,0x91,0x80,
2871 0xB5,0x94,0xC0,0x01,0x98,0x09,0x84,0xB0,0x80,0x7A,0x08,0x18,0x90,0xA8,0x6A,0x1C,
2872 0x39,0x2A,0xB7,0x98,0x19,0x10,0x2A,0xA1,0x10,0xBD,0x39,0x18,0x2D,0x39,0x3F,0x10,
2873 0x3F,0x01,0x09,0x19,0x0A,0x38,0x8C,0x40,0xB3,0xB4,0x93,0xAD,0x20,0x2B,0xD4,0x81,
2874 0xC3,0xB0,0x39,0xA0,0x23,0xD8,0x04,0xB1,0x9B,0xA7,0x1A,0x92,0x08,0xA5,0x88,0x81,
2875 0xE2,0x01,0xB8,0x01,0x81,0xC1,0xC7,0x90,0x92,0x80,0xA1,0x97,0xA0,0xA2,0x82,0xB8,
2876 0x18,0x00,0x9C,0x78,0x98,0x83,0x0B,0x0B,0x32,0x7D,0x19,0x10,0xA1,0x19,0x09,0x0A,
2877 0x78,0xA8,0x10,0x1B,0x29,0x29,0x1A,0x14,0x2F,0x88,0x4A,0x1B,0x10,0x10,0xAB,0x79,
2878 0x0D,0x49,0x18,0xA0,0x02,0x1F,0x19,0x3A,0x2B,0x11,0x8A,0x88,0x79,0x8A,0x20,0x49,
2879 0x9B,0x58,0x0B,0x28,0x18,0xA9,0x3A,0x7D,0x00,0x29,0x88,0x82,0x3D,0x1A,0x38,0xBA,
2880 0x15,0x09,0xAA,0x51,0x8B,0x83,0x3C,0x8A,0x58,0x1B,0xB5,0x01,0xBB,0x50,0x19,0x99,
2881 0x24,0xCA,0x21,0x1B,0xA2,0x87,0xA8,0xB1,0x68,0xA1,0xA6,0xA2,0xA8,0x29,0x8B,0x24,
2882 0xB4,0xE2,0x92,0x8A,0x00,0x19,0x93,0xB5,0xB4,0xB1,0x81,0xB1,0x03,0x9A,0x82,0xA7,
2883 0x90,0xD6,0xA0,0x80,0x1B,0x29,0x01,0xA4,0xE1,0x18,0x0A,0x2A,0x29,0x92,0xC7,0xA8,
2884 0x81,0x19,0x89,0x30,0x10,0xE0,0x30,0xB8,0x10,0x0C,0x1A,0x79,0x1B,0xA7,0x80,0xA0,
2885 0x00,0x0B,0x28,0x18,0xB1,0x85,0x1E,0x00,0x20,0xA9,0x18,0x18,0x1C,0x13,0xBC,0x15,
2886 0x99,0x2E,0x12,0x00,0xE1,0x00,0x0B,0x3B,0x21,0x90,0x06,0xC9,0x2A,0x49,0x0A,0x18,
2887 0x20,0xD1,0x3C,0x08,0x00,0x83,0xC9,0x41,0x8E,0x18,0x08,0x02,0xA0,0x09,0xA4,0x7B,
2888 0x90,0x19,0x2A,0x10,0x2A,0xA8,0x71,0xBA,0x10,0x4A,0x0E,0x22,0xB2,0xB2,0x1B,0x8C,
2889 0x78,0x1A,0xB5,0x93,0xA9,0x1B,0x49,0x19,0x29,0xA3,0xC6,0x88,0xAA,0x32,0x0D,0x1B,
2890 0x22,0x08,0xC2,0x18,0xB9,0x79,0x3F,0x01,0x10,0xA9,0x84,0x1C,0x09,0x21,0xB0,0xA7,
2891 0x0A,0x99,0x50,0x0C,0x81,0x28,0x8B,0x48,0x2E,0x00,0x08,0x99,0x38,0x5B,0x88,0x14,
2892 0xA9,0x08,0x11,0xAA,0x72,0xC1,0xB3,0x09,0x8A,0x05,0x91,0xF2,0x81,0xA1,0x09,0x02,
2893 0xF2,0x92,0x99,0x1A,0x49,0x80,0xC5,0x90,0x90,0x18,0x09,0x12,0xA1,0xF2,0x81,0x98,
2894 0xC6,0x91,0xA0,0x11,0xA0,0x94,0xB4,0xF2,0x81,0x8B,0x03,0x80,0xD2,0x93,0xA8,0x88,
2895 0x69,0xA0,0x03,0xB8,0x88,0x32,0xBC,0x97,0x80,0xB1,0x3B,0x1A,0xA6,0x00,0xD1,0x01,
2896 0x0B,0x3B,0x30,0x9B,0x31,0x3E,0x92,0x19,0x8A,0xD3,0x5C,0x1B,0x41,0xA0,0x93,0xA2,
2897 0xAF,0x39,0x4C,0x01,0x92,0xA8,0x81,0x3C,0x0D,0x78,0x98,0x00,0x19,0x0A,0x20,0x2D,
2898 0x29,0x3C,0x1B,0x48,0x88,0x99,0x7A,0x2D,0x29,0x2A,0x82,0x80,0xA8,0x49,0x3E,0x19,
2899 0x11,0x98,0x82,0x9A,0x3B,0x28,0x2F,0x20,0x4C,0x90,0x29,0x19,0x9A,0x7A,0x29,0x28,
2900 0x98,0x88,0x33,0xCD,0x11,0x3A,0xC1,0xA4,0xA0,0xC4,0x82,0xC8,0x50,0x98,0xB2,0x21,
2901 0xC0,0xB6,0x98,0x82,0x80,0x9C,0x23,0x00,0xF8,0x30,0xA8,0x1A,0x68,0xA8,0x86,0x9A,
2902 0x01,0x2A,0x0A,0x97,0x91,0xC1,0x18,0x89,0x02,0x83,0xE0,0x01,0x8B,0x29,0x30,0xE2,
2903 0x91,0x0B,0x18,0x3B,0x1C,0x11,0x28,0xAC,0x78,0x80,0x93,0x91,0xA9,0x49,0x8B,0x87,
2904 0x90,0x99,0x3D,0x5A,0x81,0x08,0xA1,0x11,0x2F,0x1A,0x21,0x9B,0x15,0xA2,0xB0,0x11,
2905 0xC0,0x91,0x5B,0x98,0x24,0xA2,0xF2,0x92,0x8B,0x6A,0x18,0x81,0xB5,0xB1,0x88,0x4C,
2906 0x00,0x00,0xA4,0xC1,0x2B,0x1A,0x59,0x0A,0x02,0x80,0x1E,0x02,0x08,0xB3,0x80,0x9A,
2907 0x23,0xB8,0xF2,0x84,0xAB,0x01,0x48,0x90,0xA7,0x90,0x0A,0x29,0x09,0x95,0x99,0xA0,
2908 0x59,0x2B,0x00,0x97,0xB0,0x29,0x89,0x2A,0x03,0xD0,0xB7,0x1B,0x81,0x00,0xA6,0xB1,
2909 0x90,0x09,0x48,0xC0,0x11,0x00,0x8A,0x00,0x5B,0x83,0x9A,0x18,0x2F,0x3C,0x18,0x11,
2910 0xA9,0x04,0x1A,0x4F,0x01,0x98,0x81,0x09,0x09,0x4A,0x18,0xB4,0xA2,0x0B,0x59,0x90,
2911 0x3B,0x49,0xBC,0x40,0x6A,0x88,0x3A,0x08,0x3E,0x3A,0x80,0x93,0xB0,0xE1,0x5A,0x00,
2912 0xA4,0xB3,0xE3,0x90,0x0D,0x38,0x09,0x82,0xC4,0xA1,0xB1,0x4C,0x18,0x10,0x91,0xB2,
2913 0x13,0xEA,0x34,0x99,0x88,0xA6,0x89,0x92,0x91,0xC1,0x20,0xB2,0xC2,0x86,0xD2,0xB3,
2914 0x80,0xB2,0x08,0x09,0x87,0x91,0xC0,0x11,0x89,0x90,0x28,0xB9,0x79,0x19,0xA4,0x82,
2915 0xD0,0x03,0x0C,0xA3,0xA5,0xB2,0xB2,0x1B,0x29,0x13,0xF1,0xB4,0x81,0x9D,0x38,0x00,
2916 0xC4,0xA1,0x89,0x59,0x1A,0x81,0xA4,0xA9,0x1C,0x6A,0x19,0x02,0xB1,0x1A,0x4A,0x0B,
2917 0x78,0x89,0x81,0x1C,0x2A,0x29,0x4A,0xA3,0x3E,0x1C,0x49,0x1A,0x08,0x21,0xAE,0x28,
2918 0x4B,0x19,0x20,0x8C,0x10,0x3A,0xAB,0x26,0x8B,0x18,0x59,0x99,0x13,0xA2,0xAB,0x79,
2919 0x2F,0x18,0x10,0xB2,0x80,0x1B,0x4D,0x5A,0x80,0x82,0x98,0x81,0x80,0x09,0xA5,0x90,
2920 0x91,0x03,0xC2,0xE2,0x81,0xA8,0x82,0x09,0xC6,0xA3,0xB1,0x08,0x5B,0x08,0x05,0xD1,
2921 0xA2,0x89,0x2A,0x28,0x91,0xA6,0x88,0xB0,0x49,0x80,0x09,0x08,0x88,0x07,0xB8,0x05,
2922 0x99,0x81,0x88,0x18,0xE2,0x00,0xC3,0x18,0x0D,0x10,0x30,0xD0,0x93,0x8A,0x09,0x10,
2923 0x2F,0x11,0x90,0xA1,0x20,0x9B,0xB1,0x73,0xC8,0x94,0x98,0x3B,0x01,0x0C,0x30,0x19,
2924 0xF8,0x12,0x90,0xBA,0x78,0x0A,0x11,0x98,0xA0,0x79,0x8A,0x30,0x2B,0xC2,0x11,0x0D,
2925 0x09,0x7A,0x00,0x82,0xB9,0x01,0x7A,0x89,0x21,0x09,0xA1,0x0A,0x7C,0x10,0x88,0xB5,
2926 0x88,0x0A,0x2B,0x69,0x1A,0x10,0xA0,0x5B,0x19,0x1A,0x10,0x19,0x1A,0x6C,0x20,0x90,
2927 0xA5,0x98,0x1B,0x0A,0x69,0x82,0xD1,0x18,0x09,0x19,0x2A,0x93,0xD4,0x9A,0x01,0x49,
2928 0xA2,0xA2,0x82,0xD8,0x22,0xAA,0x97,0xA9,0x2D,0x38,0x2A,0xB6,0x80,0x90,0x0A,0x3C,
2929 0x82,0x94,0xB8,0x21,0x0E,0x2A,0x22,0xB8,0x00,0x4F,0x2B,0x3A,0x81,0xA1,0x29,0x2C,
2930 0x6A,0x13,0xD1,0xA2,0x98,0x28,0x0C,0x01,0xD5,0x08,0xA9,0x31,0xB3,0xB0,0xA7,0xB0,
2931 0x29,0x1B,0x87,0xA2,0xA1,0xB2,0x4A,0x89,0x11,0xC3,0xF3,0x98,0x08,0x03,0xA0,0xA3,
2932 0xC5,0x90,0xB3,0xB5,0xB4,0xB8,0x02,0x91,0x91,0xD3,0xA4,0xC1,0x1B,0x82,0x28,0xA4,
2933 0xD1,0x94,0x8A,0x28,0x08,0x03,0xE0,0x80,0xD4,0x90,0x91,0xA1,0x3B,0x3D,0x02,0xE4,
2934 0xA1,0x92,0x89,0x1A,0x4B,0x95,0xB3,0x90,0x99,0x6A,0x0A,0x30,0xA1,0x93,0xA6,0xA9,
2935 0x85,0x8B,0x82,0x10,0xB1,0xA3,0x94,0xF8,0x38,0x9A,0x30,0x1A,0x8B,0xA7,0x89,0x01,
2936 0x5B,0x19,0x18,0x11,0xF0,0x18,0x1C,0x39,0x19,0x0C,0x12,0x1C,0x2A,0x7B,0x3A,0x88,
2937 0x2B,0x18,0x2B,0x5C,0x20,0x92,0x8D,0x38,0x8A,0x3A,0x5B,0x2E,0x3A,0x2B,0x10,0x12,
2938 0xBB,0x6A,0x4D,0x18,0x10,0xB1,0x81,0x2A,0x8B,0x79,0x80,0x01,0x0A,0x09,0x5B,0x2D,
2939 0x84,0x8A,0x08,0x02,0xA2,0x91,0x82,0xE8,0x50,0x9B,0x85,0xA3,0xB0,0xA3,0x1B,0x02,
2940 0x18,0xF3,0xA2,0x88,0xAB,0x53,0xD1,0xB4,0xA3,0x09,0x09,0x18,0xD4,0x08,0xB0,0x09,
2941 0x58,0xD1,0x82,0x89,0x81,0x1A,0x18,0x05,0xB9,0xC3,0x30,0xC0,0x95,0x80,0xC3,0x89,
2942 0x89,0x13,0x88,0xF2,0x93,0x0E,0x18,0x01,0x92,0xA5,0xB8,0x2A,0x39,0xAA,0x33,0x9A,
2943 0xB1,0x11,0xF5,0xA1,0xA1,0x0A,0x50,0xB8,0x03,0xC4,0xA0,0x4E,0x29,0x10,0x88,0xC2,
2944 0x1A,0x39,0x1D,0x28,0x98,0x94,0x0E,0x10,0x2A,0x3C,0x02,0x2D,0x1B,0x4B,0x3B,0x49,
2945 0x19,0xA9,0x48,0x2F,0x29,0x10,0x89,0x02,0x0C,0x10,0x09,0xB9,0x70,0x1B,0x8A,0x50,
2946 0xA8,0x2B,0x49,0x89,0x69,0x88,0x95,0x89,0x90,0x92,0x4C,0x19,0x82,0xC1,0x01,0x80,
2947 0xA0,0x2B,0x7A,0x81,0x10,0xC2,0xB7,0x98,0x88,0x19,0x2C,0x03,0xB1,0xA4,0xA1,0x0C,
2948 0x3B,0x78,0x88,0x85,0xB1,0xA0,0x1B,0x3A,0x4A,0x08,0x94,0x81,0xF1,0x80,0x00,0x0C,
2949 0x59,0x09,0x18,0x90,0xA6,0x92,0x8C,0x1A,0x79,0x92,0xA8,0x00,0x81,0x2E,0x2A,0x13,
2950 0xA2,0xB0,0xA5,0x88,0x88,0x89,0x11,0x19,0xA0,0xF3,0x82,0xB0,0x83,0x5F,0x2A,0x01,
2951 0xA1,0x94,0xB0,0x09,0x78,0x98,0xA3,0xA6,0xA0,0x91,0x80,0x93,0x98,0xC1,0x12,0x18,
2952 0xC9,0x17,0xA0,0xA0,0x1A,0x21,0x80,0x99,0xD4,0x30,0x9D,0x00,0x10,0x2F,0x08,0x1C,
2953 0x21,0x08,0xB4,0xC3,0x2B,0xA9,0x52,0xD2,0xA3,0xD1,0x09,0x10,0x8B,0x24,0x92,0xD1,
2954 0x80,0x19,0xA0,0x2C,0x12,0x49,0xAA,0xB6,0x95,0xB8,0x08,0x3A,0x2B,0x01,0xF3,0xB3,
2955 0x0B,0x09,0x79,0x18,0xA2,0xA4,0xA0,0x18,0x0C,0x20,0x08,0xA9,0x16,0x0C,0x00,0x1B,
2956 0x08,0x2B,0x7B,0x01,0x01,0xB9,0x59,0x19,0x8B,0x45,0xA8,0x80,0x0C,0x1A,0x41,0x1E,
2957 0x00,0x28,0xA8,0x5A,0x00,0xC1,0x49,0x99,0x21,0x1D,0x08,0x85,0x99,0x95,0x89,0x90,
2958 0x11,0x90,0xD1,0x28,0xB2,0xA7,0x99,0x81,0x02,0xAC,0x13,0x81,0xB2,0xA6,0xA9,0x28,
2959 0x1C,0xB1,0x33,0xD1,0xC1,0x58,0xA8,0x14,0xB0,0xB7,0x91,0xA0,0x82,0x89,0xC2,0x28,
2960 0xA1,0xB2,0x49,0xD2,0x94,0xC8,0x12,0x80,0x99,0x85,0x08,0xD3,0x09,0xA2,0xB3,0x1E,
2961 0x08,0x21,0xB9,0x23,0xB4,0xAB,0x41,0xAC,0x87,0x09,0xA2,0xC5,0x0B,0x2A,0x5A,0x91,
2962 0x20,0x9A,0x89,0x78,0x9B,0x31,0x89,0x80,0x29,0x0A,0xB7,0x3C,0x98,0x48,0x1D,0x00,
2963 0x01,0xB0,0x20,0x2F,0x29,0x4A,0x89,0x94,0x1C,0x88,0x28,0x2B,0x10,0x88,0x9A,0x71,
2964 0x9A,0x08,0x4A,0x2F,0x18,0x2B,0x18,0x02,0xA8,0x4B,0x7A,0x99,0x48,0x80,0xA8,0x20,
2965 0x1D,0x40,0xA8,0x10,0x08,0xA8,0xC5,0x88,0xC2,0x18,0x88,0x2A,0x12,0xF3,0x82,0xD8,
2966 0x20,0x0A,0x09,0xA6,0x98,0x04,0xB9,0x11,0x18,0xC3,0xE1,0x29,0xA1,0x11,0xC1,0x03,
2967 0xE2,0x9A,0x33,0xA9,0xB5,0x98,0x92,0xA1,0x02,0xF8,0x21,0xA8,0x10,0x02,0xC1,0xB7,
2968 0x1B,0x90,0x5B,0x3C,0x83,0x93,0xE0,0x19,0x1A,0x11,0x11,0xF1,0x92,0x89,0x19,0x2C,
2969 0x2C,0x41,0x99,0x92,0x90,0x3F,0x18,0x4B,0x00,0x08,0xD2,0x01,0xB2,0xAA,0x78,0x09,
2970 0x01,0x91,0xA2,0x98,0x2F,0x3A,0x2C,0x01,0x00,0x93,0xE0,0x28,0x2C,0x2B,0x01,0x12,
2971 0xE1,0x80,0xB3,0x3D,0x3A,0x0A,0x50,0x98,0xC2,0xA0,0x11,0xAA,0x30,0x87,0x90,0xC2,
2972 0x29,0x88,0x38,0xC8,0xB5,0x90,0xBA,0x70,0x1A,0x02,0x94,0xD0,0x80,0x1A,0x82,0xA6,
2973 0xB0,0x91,0x18,0xB3,0x00,0x13,0xF1,0xA2,0xC1,0x82,0xB0,0x00,0x15,0x0B,0xD3,0x02,
2974 0xA8,0x91,0x2B,0x1F,0x49,0x88,0xA6,0x80,0x88,0x08,0x1B,0xA5,0x80,0xB9,0x06,0x0B,
2975 0x90,0x21,0x9D,0x48,0x18,0xA0,0x15,0xC9,0x82,0x2B,0x1A,0x42,0x9A,0xC4,0x39,0xBC,
2976 0x69,0x00,0xA0,0x29,0x8C,0x39,0x59,0x08,0x09,0x49,0xA9,0x6B,0x81,0x00,0x98,0xB0,
2977 0x68,0x3D,0x81,0x88,0x18,0x19,0x1D,0x12,0x80,0xB2,0x3A,0x3F,0x85,0x92,0xD0,0x00,
2978 0x0A,0x19,0x12,0xF1,0x02,0x9B,0x19,0x40,0xB9,0x11,0x02,0xF2,0x1A,0x08,0x94,0x0A,
2979 0xC2,0x83,0x0B,0xB4,0xA4,0xC0,0x32,0xD8,0x86,0x98,0x90,0x95,0x89,0xA3,0x83,0xC2,
2980 0x92,0xE1,0x92,0x82,0xD9,0x03,0x08,0xA9,0x85,0x92,0xA2,0x80,0xE0,0x30,0x8B,0xB3,
2981 0x87,0x89,0x90,0x83,0xA0,0x08,0x92,0x93,0x3E,0xAB,0x43,0x89,0xE3,0x80,0x83,0x2F,
2982 0x00,0xA3,0x80,0xC9,0x22,0x3F,0x08,0x81,0x0B,0x33,0x9A,0xA3,0x7B,0x0C,0x29,0x4A,
2983 0x1B,0x21,0xAA,0x70,0x1B,0x0D,0x48,0x1A,0x81,0x88,0xB1,0x39,0x3F,0x08,0x58,0xA0,
2984 0x81,0x1A,0x1A,0x2B,0x6D,0x11,0x0A,0x91,0x01,0x1A,0x98,0x5A,0x0C,0x03,0xB1,0x84,
2985 0xA3,0xAD,0x58,0x2A,0xA1,0x84,0xB1,0xA0,0x5C,0x2B,0x13,0xA8,0x95,0x83,0xE8,0x10,
2986 0x81,0xB0,0x00,0xC2,0x96,0xA0,0x91,0x00,0x2C,0x90,0x30,0xF2,0x80,0xA8,0x39,0x21,
2987 0xC1,0x03,0xAC,0x39,0x7C,0x29,0x91,0x1A,0x00,0x19,0x2C,0x3A,0x93,0xB0,0x29,0x8F,
2988 0x28,0x02,0x93,0xF3,0xA9,0x01,0x03,0xE0,0x08,0x09,0x1D,0x58,0xA1,0x83,0xA9,0x6B,
2989 0x2A,0x3C,0x21,0x89,0xC2,0x2C,0x4B,0x8A,0x50,0x81,0x98,0xA8,0x32,0x0C,0x8E,0x24,
2990 0x0B,0x1A,0x81,0x92,0xA1,0x4F,0x18,0x3A,0x0A,0xB4,0x18,0x2E,0x39,0x82,0x19,0xD3,
2991 0xD0,0x28,0x1B,0x11,0x98,0x07,0xAA,0x28,0x00,0x88,0xB4,0x89,0x1B,0x1F,0x22,0x00,
2992 0xB3,0xC9,0x33,0xAB,0x2B,0xB5,0x48,0x98,0x98,0xA7,0x10,0xD2,0xC1,0x23,0xCA,0x93,
2993 0xC6,0x80,0xA1,0x88,0x02,0x89,0xE2,0x09,0x38,0xBA,0x40,0x89,0x21,0xD8,0x49,0x10,
2994 0x8D,0x02,0x90,0xC3,0x9A,0x24,0x89,0x08,0x84,0xA5,0x9C,0x10,0x11,0x9C,0x88,0x30,
2995 0x3C,0xA1,0x94,0x58,0x8C,0x0B,0x69,0x29,0x9A,0x81,0x12,0x2B,0x8B,0x79,0x94,0xB0,
2996 0xC1,0x84,0xC2,0x99,0x25,0x99,0x11,0xA2,0x93,0xE4,0x99,0x80,0x0A,0x00,0x10,0xB7,
2997 0xB0,0x31,0xBA,0x3C,0x21,0xB3,0xF1,0x18,0xA0,0x2A,0x20,0xA3,0x06,0xE8,0x28,0xA1,
2998 0xB4,0x08,0x0B,0x11,0x4B,0xB7,0x90,0xA5,0x98,0x3D,0x19,0x02,0xA1,0xC4,0xB2,0x19,
2999 0x28,0xC0,0xA5,0x92,0xB1,0xA3,0x0A,0x0A,0x08,0x2B,0x70,0xC4,0xB3,0x00,0xBC,0x4B,
3000 0x39,0x12,0xE3,0xA0,0x00,0x3F,0x18,0x29,0x94,0xD1,0x19,0x09,0x00,0xA1,0x83,0x99,
3001 0x9B,0x35,0x80,0xC4,0xB1,0x6A,0x1A,0x1C,0x29,0x38,0x0E,0x19,0x5A,0x1A,0x82,0x8A,
3002 0x59,0x2A,0x2E,0x20,0x88,0xA8,0x3A,0x38,0x3D,0x00,0xB3,0x29,0xAD,0x49,0x10,0x0C,
3003 0x01,0x01,0xA3,0x8F,0x85,0x09,0x1B,0x88,0x10,0xA3,0xD2,0x90,0x3C,0x5C,0x39,0x03,
3004 0xD1,0xA0,0x00,0x2A,0x0B,0x04,0xA7,0x90,0xA0,0x11,0x90,0x99,0x83,0xB4,0xB1,0xF1,
3005 0x84,0x88,0x90,0x18,0x18,0xD3,0xD2,0xB3,0xA0,0x1A,0x21,0xA7,0xB2,0xB3,0x92,0x9A,
3006 0x22,0xB9,0x28,0x38,0xBD,0x87,0x2A,0xB1,0x13,0x0D,0x0A,0x38,0xC9,0x24,0xC0,0x19,
3007 0x23,0x0F,0x01,0x88,0xC0,0x2A,0x82,0x18,0x28,0xF0,0x18,0x2A,0x29,0x4B,0x35,0xB8,
3008 0xA3,0x9D,0x18,0x1B,0x40,0x00,0x9A,0x5C,0x3A,0x09,0x2F,0x38,0x8A,0x3B,0x3B,0x11,
3009 0x5C,0x19,0x2B,0x4A,0x08,0x0A,0x3D,0x20,0x4F,0x3A,0x19,0x2A,0x18,0x4D,0x1B,0x3A,
3010 0x11,0x0D,0x3A,0x3C,0x4B,0x93,0x81,0xAA,0x6B,0x4A,0x18,0x00,0xC3,0xC3,0x9A,0x59,
3011 0x2A,0x1B,0xA7,0xA1,0x81,0x88,0x88,0x58,0xB2,0xB1,0x2B,0x83,0xD4,0x81,0x08,0x0F,
3012 0x00,0x20,0xC2,0xE2,0x80,0x08,0x1C,0x29,0x04,0xB1,0xA2,0x01,0x1C,0x91,0x00,0x0C,
3013 0x49,0xB0,0x43,0xF2,0x99,0x39,0x3F,0x00,0x81,0x94,0xC1,0x09,0x1A,0x69,0x90,0x80,
3014 0x94,0xAA,0x20,0x2A,0x91,0xB1,0x39,0x7A,0x38,0xD1,0x10,0x8A,0x8C,0x5A,0x01,0xB5,
3015 0x98,0x80,0x2A,0x0B,0x32,0x92,0xF1,0x81,0x9A,0x23,0x8A,0xA3,0xB7,0x09,0x03,0x08,
3016 0xD0,0x94,0x9A,0x09,0x01,0x93,0xB7,0xC2,0x8C,0x3A,0x83,0x99,0x05,0xA0,0x0B,0x29,
3017 0x93,0xE5,0x80,0x89,0x38,0x90,0x8A,0xD7,0xA1,0x19,0x1B,0x48,0x98,0x92,0xC3,0xA1,
3018 0x09,0x3F,0x02,0x0C,0x22,0xC3,0xB2,0xA1,0x01,0x9F,0x4A,0x01,0xA3,0xD3,0xB0,0x28,
3019 0x3F,0x29,0x20,0xA2,0xC2,0xB1,0x08,0x5A,0x98,0x13,0xD2,0xC1,0x01,0xB2,0x80,0x3D,
3020 0x03,0xC1,0x89,0x96,0x90,0x90,0x3A,0x1A,0x9A,0x32,0xB6,0xA2,0x8E,0x4A,0x28,0x8A,
3021 0x84,0xA2,0x8A,0x2D,0x49,0x09,0x88,0x18,0x30,0x9D,0x2C,0x23,0xB1,0x0C,0x92,0x2D,
3022 0x39,0x82,0xC4,0x2E,0x10,0x1A,0x10,0xB9,0x48,0x19,0x39,0xBA,0x34,0xDA,0x2D,0x48,
3023 0x1A,0xA6,0x98,0x83,0x9A,0x1D,0x38,0x04,0xD0,0x18,0x90,0x2C,0x11,0x93,0xD3,0x9A,
3024 0x11,0x08,0x82,0xF1,0x01,0xA0,0x2A,0x93,0xD3,0xB4,0xB8,0x82,0x2F,0x11,0xA3,0xB3,
3025 0xA8,0x3B,0x09,0x23,0x96,0xC8,0x3B,0x3F,0x93,0x82,0xA1,0x90,0x3F,0x28,0x81,0xD1,
3026 0x93,0x08,0x2D,0x18,0x91,0xB3,0xB5,0x98,0x2A,0x2B,0x84,0xB1,0x5B,0x8A,0x31,0x18,
3027 0x80,0x8B,0x7E,0x39,0x2B,0x02,0xC1,0x8B,0x6C,0x49,0x09,0x10,0xA1,0x08,0x01,0x0C,
3028 0x20,0xA1,0x09,0x4F,0x18,0x00,0x01,0xA0,0x5C,0x1B,0x5B,0x10,0x92,0x90,0x2B,0x5A,
3029 0x3D,0x18,0x91,0x19,0x98,0x2D,0x39,0x89,0x2D,0x3A,0x48,0x2C,0x11,0xB5,0x9A,0x19,
3030 0x5B,0x28,0x90,0x95,0x98,0x89,0x2B,0x40,0x08,0x90,0xF3,0x0A,0x08,0xA6,0x80,0x91,
3031 0xB2,0xA0,0x02,0xF2,0xA1,0xB7,0x89,0x81,0x82,0x91,0xB1,0x21,0xAB,0x32,0xE9,0x04,
3032 0xA2,0x8D,0x12,0x91,0xA3,0xA3,0xD2,0x8B,0x39,0xD1,0x84,0xE2,0x90,0x00,0x2B,0x29,
3033 0xA3,0xD4,0xA1,0x91,0x1D,0x5A,0x08,0x19,0x11,0x99,0x08,0x18,0x49,0x0F,0x18,0x10,
3034 0x82,0xF1,0x00,0x89,0x2F,0x3A,0x01,0xB3,0xC2,0x81,0x3F,0x29,0x08,0x10,0xA1,0xA1,
3035 0x3B,0x5D,0x19,0x28,0x0B,0x38,0x82,0x91,0x19,0xBD,0x3B,0x7A,0x80,0x12,0xB3,0xE0,
3036 0x0B,0x6A,0x01,0x88,0xA4,0x08,0x0B,0x08,0x59,0x80,0x80,0x1D,0x49,0x89,0x00,0x84,
3037 0x99,0x1A,0x2B,0x32,0xE3,0xB4,0xA9,0x3A,0x99,0x31,0xE3,0xAA,0x58,0x3B,0x88,0x95,
3038 0xC0,0x18,0x4A,0x09,0x30,0xF2,0xA3,0x1C,0x1B,0x49,0x00,0xD3,0xB2,0xA0,0x18,0x11,
3039 0x92,0xD3,0xB2,0x91,0x80,0xE7,0xA1,0x91,0x98,0x19,0x22,0xC2,0xD2,0x18,0x8D,0x3B,
3040 0x10,0xA5,0x91,0x98,0x02,0x3E,0x80,0x01,0x90,0xAA,0x13,0xF1,0x02,0xD1,0x08,0x19,
3041 0x49,0xB4,0x91,0xB4,0x99,0x2A,0x0C,0x32,0xC0,0x05,0x88,0x0B,0x80,0x2C,0x81,0x10,
3042 0x0B,0x51,0xA9,0x19,0x05,0xBF,0x28,0x20,0xE1,0x90,0x80,0x28,0x19,0x08,0x26,0xB1,
3043 0xA1,0x18,0x88,0x2A,0xF0,0x12,0x8A,0xB3,0x14,0x1B,0xD4,0xD8,0x10,0x08,0x8A,0x17,
3044 0xA0,0x98,0x2B,0x3A,0x29,0x48,0xA4,0x99,0x0E,0x4A,0x12,0x8B,0x31,0x8B,0x4E,0x1A,
3045 0x11,0xB5,0x89,0x91,0x29,0x89,0xC2,0x97,0x90,0x0A,0x19,0x11,0x91,0xC1,0xD5,0x08,
3046 0x89,0x20,0x91,0xB1,0x1A,0x2D,0x18,0x29,0xD2,0x3B,0x3E,0x3A,0x2A,0x90,0x82,0x1C,
3047 0x49,0x3B,0x93,0xB6,0xC8,0x4C,0x02,0x91,0x93,0xF2,0x88,0x2D,0x28,0x81,0x82,0xC1,
3048 0x89,0x2D,0x6B,0x19,0x82,0x80,0x18,0x8B,0x39,0x39,0xC8,0x3A,0x6A,0x0A,0x22,0xD2,
3049 0x09,0x2C,0x1A,0x68,0x92,0xE2,0x89,0x2A,0x2A,0x30,0xC2,0xA3,0xB4,0x1D,0x2A,0x09,
3050 0x93,0x18,0xF2,0x89,0x28,0xB3,0x01,0x8F,0x18,0x11,0xA1,0x93,0x90,0xD1,0x7A,0x20,
3051 0xC3,0xA2,0xA8,0x88,0x1D,0x28,0xA5,0xA2,0xA2,0x0B,0x29,0x2B,0x87,0xC1,0x80,0x0A,
3052 0x19,0x01,0x12,0xF1,0x10,0x80,0x0A,0x18,0x08,0x2F,0x4A,0x02,0x89,0x1B,0x29,0x5D,
3053 0x4C,0x08,0x82,0xA1,0x0A,0x3A,0x4B,0x29,0xC6,0xC3,0x09,0x09,0x88,0x39,0x98,0x82,
3054 0xA5,0x1A,0x30,0x11,0xBD,0x3F,0x12,0x8B,0x28,0xC3,0x88,0x3F,0x2B,0x3B,0x48,0xA1,
3055 0x80,0x8A,0x4D,0x39,0x01,0x93,0xA2,0xF1,0x19,0x19,0x0A,0x02,0xB2,0x8B,0x24,0xD2,
3056 0x4B,0x12,0xC8,0x2E,0x10,0xB5,0x89,0x01,0x09,0x1C,0x2A,0x03,0xD4,0x91,0x98,0x99,
3057 0x11,0x2B,0xE4,0x00,0x00,0x01,0xE0,0xA5,0x89,0x99,0x31,0x18,0xD0,0xB7,0x98,0x18,
3058 0x0A,0x10,0x94,0xC2,0x90,0x18,0x00,0x99,0x87,0xA0,0x90,0x2A,0x3C,0x02,0xB8,0xC1,
3059 0x79,0x1A,0x20,0x08,0xA1,0xD2,0x1C,0x29,0x03,0xD1,0x29,0x99,0x2C,0x50,0xB3,0xD1,
3060 0x08,0x09,0x3C,0x10,0x04,0xB2,0x0D,0x2B,0x59,0x80,0x90,0x01,0x0F,0x3A,0x18,0x01,
3061 0xA2,0x9B,0x5B,0x3D,0x81,0x03,0xD2,0x98,0x59,0x90,0x81,0x92,0xB4,0x8B,0x1B,0x40,
3062 0xB2,0xB5,0x08,0x4B,0x01,0x09,0xD1,0x91,0x8B,0x7A,0x10,0xB3,0xC3,0x99,0x49,0x1A,
3063 0x29,0xB5,0xA2,0xAB,0x40,0x81,0x19,0xB7,0xB0,0x20,0x2B,0xD4,0x88,0xA1,0x91,0x3C,
3064 0x82,0x37,0xD3,0xB1,0x8A,0x1B,0x30,0xB3,0xF4,0xA1,0x91,0x09,0x10,0x03,0xD0,0x83,
3065 0xA9,0x8F,0x10,0x01,0x90,0x18,0x80,0x20,0x2B,0xF1,0x28,0x99,0x2A,0x41,0xF0,0x12,
3066 0xAA,0x83,0x82,0xD1,0xC1,0x08,0x89,0x59,0x09,0x83,0x87,0xB0,0x2A,0x4D,0x18,0x09,
3067 0x19,0xB3,0x4B,0x3F,0x39,0x19,0x09,0x01,0x89,0x03,0x1F,0x00,0x1A,0x0B,0x10,0x68,
3068 0xA0,0x18,0x8C,0x6A,0x09,0x08,0x97,0xA1,0x81,0x1B,0x2B,0x4C,0x03,0xB4,0xA8,0x92,
3069 0x4B,0x3C,0xA1,0x81,0x95,0xA8,0x81,0x12,0xBB,0x92,0x45,0xB9,0x93,0xF4,0x88,0x0A,
3070 0x2D,0x28,0x00,0xA3,0xA3,0x8A,0x3F,0x48,0xB1,0x92,0xB4,0xA8,0x30,0x80,0xD3,0x80,
3071 0xD1,0x19,0x3B,0xC4,0x81,0xC1,0x29,0x0D,0x20,0x13,0xC8,0xB4,0x4C,0x09,0x00,0x82,
3072 0xC2,0x3B,0x0D,0x30,0x0B,0x12,0xF0,0x1B,0x20,0x0A,0xA6,0x80,0x0A,0x4A,0x4A,0x80,
3073 0x94,0xB1,0x2E,0x3B,0x1A,0x10,0x93,0x10,0x4C,0x3D,0x08,0x82,0xC9,0x19,0x6A,0x2B,
3074 0x38,0xD1,0x08,0x19,0x2A,0x5A,0x82,0xB1,0x8D,0x29,0x78,0x09,0x82,0x0A,0x2C,0x1B,
3075 0x19,0x41,0xB8,0x8C,0x79,0x2B,0x11,0x88,0x82,0x91,0xDC,0x28,0x11,0xB0,0x11,0x18,
3076 0xC9,0x62,0xA1,0x91,0x98,0x3B,0x3A,0xB0,0xF4,0x01,0xC0,0x29,0x39,0xF8,0x95,0x91,
3077 0x88,0x88,0x91,0x03,0xA1,0xE2,0x18,0x82,0xD1,0xA2,0xD1,0x80,0x19,0x20,0x83,0xB1,
3078 0xE3,0x80,0x91,0x4D,0x1A,0x03,0xB2,0x09,0x18,0xD1,0x19,0x09,0x92,0xA6,0xA0,0xB6,
3079 0xB2,0x8B,0x38,0x10,0x42,0xD3,0xD0,0xA8,0x20,0x2C,0x10,0x01,0xB1,0xB4,0xAB,0x5B,
3080 0x79,0x80,0x10,0x1A,0xA8,0x3D,0x18,0x20,0xB3,0x8F,0x18,0x01,0x00,0x09,0xF3,0x89,
3081 0x69,0x88,0x81,0x91,0x08,0xE1,0x1A,0x08,0x11,0x81,0x1E,0x29,0xA0,0x01,0x00,0x90,
3082 0x3E,0x7B,0x18,0x82,0xC3,0xA1,0x2A,0x2C,0x5B,0x81,0xA5,0x90,0x81,0x00,0x0B,0x1A,
3083 0x1C,0x2C,0x32,0xC0,0xF3,0x80,0x2D,0x2A,0x10,0x02,0xE4,0xC1,0x89,0x4A,0x09,0x01,
3084 0x03,0xD2,0x98,0x2A,0x39,0x8A,0x89,0x26,0xB1,0xB2,0x12,0xC0,0x0A,0x5A,0x18,0x98,
3085 0xF3,0x92,0x99,0x99,0x79,0x01,0xB5,0xA1,0x80,0x80,0x90,0x83,0xA0,0xE2,0x81,0x29,
3086 0x93,0x8A,0x0A,0x6A,0x1F,0x18,0x02,0xC8,0x01,0x19,0x3B,0x4A,0x98,0x17,0xA8,0x0D,
3087 0x38,0xA1,0x91,0x10,0xA2,0x2B,0x4C,0xA6,0x81,0xBA,0x21,0x4C,0x80,0x21,0xD1,0x92,
3088 0x2C,0x08,0x30,0x9F,0x93,0x2A,0x89,0x03,0x8B,0x87,0x0A,0x0D,0x12,0x98,0xA4,0x93,
3089 0xBB,0x59,0x18,0xA1,0x32,0xE9,0x84,0x08,0x8A,0x02,0xA1,0x91,0x4B,0xB4,0x20,0x88,
3090 0xF0,0x3A,0x1A,0x88,0x87,0xB1,0x92,0x0A,0x08,0x6B,0x83,0xC3,0x91,0xC0,0x2B,0x79,
3091 0x08,0x8A,0x84,0xA0,0x89,0x40,0x1B,0xA1,0x39,0x98,0x17,0xC2,0xA2,0x12,0xCD,0x20,
3092 0x89,0x92,0x25,0xB0,0x2D,0x3A,0x8B,0x58,0x2A,0xA0,0x4C,0x08,0x30,0xAE,0x82,0x59,
3093 0x89,0x1A,0x10,0xC2,0x18,0x2C,0x40,0x1E,0x01,0xA3,0x8A,0x81,0x2C,0x29,0x29,0xA9,
3094 0x13,0x51,0xAD,0x12,0x89,0x8F,0x18,0x2C,0x39,0x00,0xC1,0x10,0x3C,0x2A,0x41,0xC8,
3095 0xA2,0x91,0x0A,0x6C,0x10,0x12,0x88,0xE8,0x30,0x91,0x81,0xD8,0x01,0x1B,0x0D,0x07,
3096 0x00,0xA8,0x92,0x0A,0x28,0xD2,0xC3,0x02,0xAA,0x94,0x81,0xB4,0xB3,0x1A,0x0B,0x13,
3097 0xF9,0x16,0xA1,0x8A,0x59,0x19,0x02,0xC1,0x91,0x8B,0x3D,0x18,0x3B,0xA4,0x94,0x80,
3098 0x99,0x88,0x1C,0x79,0x0A,0x02,0x03,0xF8,0x90,0x39,0x5B,0x19,0x02,0xC3,0x90,0xBB,
3099 0x58,0x6A,0x09,0x02,0x89,0x91,0x88,0x1A,0x69,0x8A,0x19,0x15,0xA0,0xA2,0x00,0x9A,
3100 0x6B,0x49,0x88,0xA3,0x92,0xBB,0x6B,0x3D,0x38,0x01,0x98,0x91,0x3F,0x09,0x18,0x20,
3101 0x90,0x80,0xAC,0x70,0x91,0x9B,0x51,0x09,0x88,0x99,0x14,0x8B,0x98,0x83,0x79,0xA0,
3102 0x99,0x13,0x01,0x19,0xE0,0x83,0x0B,0xB0,0x0C,0x31,0x95,0xB5,0xC2,0x8A,0x39,0x20,
3103 0x80,0x39,0xF3,0xB1,0x10,0x88,0x5E,0x18,0x94,0xA1,0x88,0xA1,0x98,0x15,0xAA,0x39,
3104 0xD4,0x84,0xC0,0xA2,0xA2,0x0C,0x81,0x86,0xB5,0xA1,0xB1,0x14,0x1B,0xB1,0x02,0x92,
3105 0xC3,0xE0,0x88,0x11,0xAA,0x69,0x18,0x81,0xA3,0xB0,0x01,0xBF,0x2A,0x31,0x93,0xF1,
3106 0x00,0x89,0x18,0x19,0x11,0xD3,0xE0,0x10,0x18,0xB1,0x18,0x24,0x9A,0x2B,0xA4,0xC0,
3107 0xB0,0x31,0x6C,0x19,0xB4,0x12,0xA8,0xEA,0x58,0x10,0x8B,0x93,0x82,0x88,0x9A,0x41,
3108 0x10,0xC3,0xEA,0x41,0xA9,0x9C,0x34,0xA1,0x2A,0x79,0xA2,0x01,0xA8,0xB3,0x28,0xCC,
3109 0x41,0x9A,0xB3,0x4B,0xB3,0x27,0x8B,0x83,0x2B,0x2F,0x08,0x28,0xB2,0x80,0x2C,0x30,
3110 0x5E,0x09,0x12,0x9B,0x09,0x22,0x5B,0x19,0x8A,0x11,0x59,0x99,0xA4,0x32,0xCD,0x18,
3111 0x08,0x10,0x85,0xB3,0xB4,0x1E,0x88,0x28,0x8A,0x11,0x09,0xC0,0x79,0x80,0x91,0x3B,
3112 0x80,0x10,0x0F,0x01,0x80,0x91,0x19,0x3D,0x92,0x28,0xA8,0x37,0x9A,0x0A,0x3A,0x8A,
3113 0x45,0xA9,0xA4,0x00,0xAA,0x09,0x3D,0x59,0x20,0xE1,0x08,0x98,0x90,0x59,0x10,0x09,
3114 0xA3,0xC3,0x93,0x99,0x2B,0x69,0x11,0xD1,0xB1,0xA4,0x91,0x3C,0x89,0x83,0xF0,0x10,
3115 0x91,0xA1,0x89,0x59,0x05,0x99,0x93,0x94,0xC8,0x08,0x0A,0x09,0x17,0xB1,0x83,0xC1,
3116 0x91,0x40,0xA2,0xC2,0x98,0xC3,0xBA,0x28,0x23,0x0F,0x80,0x50,0xB8,0x19,0x10,0x96,
3117 0x98,0x8C,0x05,0x98,0x19,0x29,0x2B,0x3B,0x0A,0xE2,0x01,0x0F,0x3C,0x38,0x08,0x09,
3118 0x81,0x4A,0x6C,0x08,0x00,0x88,0x98,0x38,0x2C,0x5A,0x1B,0x20,0x1A,0x39,0xB0,0x09,
3119 0xCB,0x5B,0x49,0x09,0x71,0x00,0xC1,0x0E,0x08,0x38,0x0C,0x02,0x10,0x0E,0x10,0x8A,
3120 0x48,0x19,0x90,0x92,0x0D,0xA3,0x98,0x3B,0x79,0x19,0x01,0x10,0xE1,0x80,0x19,0x2B,
3121 0x10,0xF2,0x02,0xAB,0x84,0x9A,0x29,0xB4,0x80,0x92,0x03,0x88,0x95,0xD0,0x03,0x90,
3122 0xA0,0xC7,0xA1,0xB0,0xA2,0x02,0x18,0xB5,0xD4,0x01,0xC0,0x08,0xA2,0x93,0xA8,0xA0,
3123 0xC3,0x20,0xF3,0x90,0x00,0xD5,0x08,0x89,0xA5,0x80,0xA0,0x81,0x82,0xC2,0x09,0xD1,
3124 0x13,0xCB,0x03,0x84,0x91,0xE1,0x1B,0x12,0x08,0xAB,0x87,0x18,0xAB,0x58,0x89,0x28,
3125 0x81,0xC9,0x33,0xA9,0x80,0x2E,0x20,0x83,0xB9,0x20,0x3B,0x9E,0x7A,0x08,0x81,0x18,
3126 0x0B,0x88,0x79,0x80,0x8B,0x00,0x12,0x0E,0x89,0x51,0x1B,0x81,0xA0,0x3A,0x01,0xAF,
3127 0x11,0x28,0xBA,0x35,0x98,0x88,0x52,0xC0,0x83,0x2F,0xA9,0x11,0x0A,0x19,0x25,0xD0,
3128 0x30,0x9C,0x08,0x21,0x98,0x81,0x2A,0xF3,0x2A,0x80,0xB6,0x2B,0x08,0x93,0xE9,0x02,
3129 0x81,0x8C,0x21,0x00,0xA6,0xA9,0x94,0x01,0x8F,0x80,0x94,0x98,0x93,0xB4,0x00,0x08,
3130 0xC0,0x14,0x98,0xB3,0xB4,0xC1,0x09,0x18,0xA7,0x00,0xA3,0xC8,0x0A,0x3C,0x19,0x96,
3131 0x83,0xC1,0x99,0x19,0x4A,0x85,0x80,0xC1,0x91,0x99,0x90,0x2A,0x17,0x95,0x99,0x88,
3132 0x12,0xAE,0x39,0x08,0x92,0x84,0xB0,0xA8,0x79,0x09,0x19,0x01,0xB2,0xA3,0x8F,0x28,
3133 0x2B,0xA2,0x40,0x82,0xA0,0x4C,0xA9,0x39,0x8D,0x81,0x70,0x88,0xA0,0x1A,0x49,0x2D,
3134 0x1A,0x26,0xA8,0x98,0x08,0x29,0x0B,0x12,0x96,0xB1,0xB2,0x3A,0x13,0x9B,0x60,0xA0,
3135 0x88,0xB2,0x34,0xEA,0x1A,0x2A,0x79,0x98,0x10,0x04,0x8C,0x1C,0x81,0x04,0x8C,0x83,
3136 0x19,0x2F,0x81,0x93,0x98,0x10,0x08,0x30,0x2A,0xFA,0x05,0x08,0x2A,0x89,0x91,0xA3,
3137 0xFA,0x11,0x11,0x00,0x8C,0x04,0x8A,0x2A,0xB5,0x10,0xA9,0xC2,0x3D,0x1B,0x32,0x04,
3138 0x0A,0x1A,0x09,0x40,0x1F,0x92,0x1D,0x2A,0x91,0x10,0x30,0x2F,0x0B,0x68,0x99,0xA2,
3139 0x92,0x88,0x78,0xA9,0x20,0x28,0xE2,0x92,0x1A,0x99,0x4B,0x19,0x22,0xA1,0xE2,0x21,
3140 0x2F,0x98,0x29,0x18,0x91,0x08,0xB0,0x79,0x1A,0x82,0x3B,0xB1,0xA7,0x8A,0xB3,0x98,
3141 0x5B,0x23,0xCA,0x42,0x83,0xF0,0x90,0x18,0x98,0x08,0xB4,0x20,0xA3,0xC0,0x43,0xD8,
3142 0x80,0x81,0xA3,0x99,0xD9,0xA7,0x19,0x90,0x10,0x05,0xB1,0x8B,0x02,0xA4,0xBD,0x23,
3143 0x93,0x8A,0x99,0x4B,0x03,0xC1,0xF8,0x38,0x09,0x2B,0x14,0xD0,0x03,0x8A,0x2A,0x39,
3144 0xB9,0x97,0x90,0xAA,0x50,0x01,0x99,0x51,0xD1,0x09,0x1A,0xB5,0x00,0x8B,0x93,0x08,
3145 0x98,0x11,0xF9,0x85,0x2B,0x08,0x96,0x89,0x90,0x2A,0x12,0x4A,0xD8,0x85,0x2B,0x0E,
3146 0x10,0x00,0x01,0xB1,0x9B,0x69,0x1A,0x90,0x40,0xB8,0x01,0x08,0x0A,0x2C,0x09,0x14,
3147 0x4B,0xE2,0x82,0x88,0xB1,0x78,0x0A,0x01,0xC2,0x93,0x19,0xCE,0x20,0x3C,0x82,0xB4,
3148 0x1B,0x20,0x8C,0x3B,0x29,0xAB,0x86,0x23,0xD8,0x81,0x9A,0x5A,0x49,0xB0,0x16,0xA0,
3149 0xB0,0x28,0x1B,0x13,0x93,0xE4,0xA2,0xA9,0x08,0x5A,0xB3,0x12,0xC1,0xE1,0x10,0x88,
3150 0x01,0x0C,0x92,0x08,0x89,0xB7,0x88,0x81,0x10,0x9A,0x17,0xA0,0xB0,0x13,0x99,0xE0,
3151 0x39,0x31,0xD2,0xB2,0x80,0x0B,0x2D,0x49,0x80,0x01,0xB0,0x06,0x09,0x0C,0x3A,0x69,
3152 0xA0,0x08,0xB2,0xA1,0x69,0x2B,0x5A,0x81,0x92,0xBA,0x21,0xB1,0x7D,0x10,0x80,0x08,
3153 0x88,0x82,0x32,0x0D,0xB0,0x1A,0x1C,0x21,0x94,0xA9,0x58,0xB9,0x5A,0x4A,0xA0,0x13,
3154 0xA9,0x80,0x7C,0x00,0x20,0x8A,0x04,0x0C,0x00,0x82,0x2A,0xB2,0xAC,0x4B,0x69,0xA0,
3155 0xA6,0x81,0x9B,0x19,0x38,0x8B,0x17,0xB2,0x81,0x2A,0xBB,0x94,0x29,0xA2,0x15,0xBA,
3156 0x97,0xA3,0xB9,0x79,0x01,0xB2,0x02,0xF1,0x90,0x0A,0x29,0x11,0x88,0xE5,0xA0,0x81,
3157 0x19,0x91,0x90,0x28,0xB3,0x14,0xD0,0xB5,0x91,0x9A,0x29,0x0B,0x07,0xA2,0xB3,0x01,
3158 0x9D,0x28,0x41,0xD0,0x91,0x90,0x82,0x1A,0xA8,0x44,0x9A,0xA9,0x21,0xE3,0xA9,0x4B,
3159 0x19,0x78,0x89,0x83,0xA3,0xB9,0x5A,0x3D,0x80,0x82,0xA2,0xA0,0x6C,0x10,0x20,0x8B,
3160 0x93,0x8B,0x0E,0x33,0xA9,0xB1,0x68,0x8A,0x31,0xAC,0x94,0xB4,0x8B,0x32,0x0B,0xB4,
3161 0x81,0x91,0x1D,0x33,0xD9,0x31,0xE1,0x8B,0x3B,0x30,0x12,0x49,0xD2,0x8E,0x29,0x18,
3162 0x8A,0x92,0x02,0xAA,0x59,0x1C,0x32,0x88,0x01,0x23,0xFB,0x83,0x29,0xDA,0x59,0x01,
3163 0x81,0x92,0xE1,0x18,0x8A,0x1D,0x30,0x93,0xF1,0x00,0x01,0x0B,0x39,0x92,0x89,0xA0,
3164 0x11,0x5B,0xE0,0x82,0x09,0x13,0xAA,0xB4,0x16,0xD8,0x91,0x2A,0x29,0x84,0x1B,0xC5,
3165 0x98,0x98,0x31,0x98,0x99,0x17,0xA9,0x20,0x92,0xC3,0x18,0x9D,0x20,0x3D,0x89,0x94,
3166 0xA2,0x1C,0x5C,0x29,0x39,0xA0,0xB3,0x00,0x0C,0x4C,0x48,0x92,0x0A,0x91,0x85,0x9A,
3167 0x01,0x82,0x1F,0x10,0x99,0x15,0xC1,0xA0,0x39,0x1A,0x1D,0x85,0xB4,0x90,0x1A,0x2A,
3168 0x4B,0x01,0xB2,0x93,0xBE,0x12,0x83,0xC9,0x18,0x09,0x20,0x78,0xF1,0x08,0x19,0x88,
3169 0x3A,0x83,0xB3,0xA9,0x93,0x7A,0x0A,0x96,0x98,0x00,0xA8,0x3A,0x30,0x92,0xF2,0x9B,
3170 0x3D,0x38,0x92,0x92,0xC3,0xB8,0x6B,0x29,0x01,0x01,0xB2,0x2F,0x09,0x19,0x18,0x01,
3171 0x3B,0x7B,0x10,0xA1,0x90,0x39,0x0F,0x38,0x0A,0xB5,0xA4,0x89,0x8B,0x6A,0x2B,0x12,
3172 0xC8,0x90,0x40,0x2A,0x9E,0x22,0x88,0x18,0x09,0x3A,0xC3,0xE8,0x09,0x59,0x08,0x12,
3173 0x94,0xD0,0x1A,0x2C,0x38,0x00,0xA1,0x83,0xE8,0x08,0x3A,0x08,0x10,0x9E,0x83,0x1D,
3174 0x92,0x19,0x2C,0x39,0x3B,0x59,0x04,0xE1,0x80,0x08,0x8D,0x21,0x81,0xB2,0xB2,0x02,
3175 0x99,0x91,0xA4,0xD6,0x98,0x99,0x03,0x80,0x98,0xA7,0x91,0x09,0xA1,0xB2,0xB3,0xE1,
3176 0x12,0x92,0xB1,0x81,0x06,0x99,0x0A,0x23,0xC4,0xB1,0xF2,0x89,0x19,0x3A,0x94,0x82,
3177 0xE0,0x89,0x38,0x0B,0xA4,0xA5,0x80,0x80,0x8C,0x34,0xB9,0xA9,0x23,0x13,0xB9,0xC1,
3178 0xC7,0x1B,0x89,0x10,0x20,0x11,0xE3,0xA8,0x4B,0x0B,0x40,0x91,0x90,0x1B,0x5F,0x2A,
3179 0x18,0x82,0x91,0x0B,0x4A,0x28,0xCA,0x40,0x80,0x5B,0x2C,0x13,0xB0,0x8A,0xA9,0x5A,
3180 0x58,0x89,0x82,0x88,0x2E,0x3B,0x31,0xA1,0x9B,0x01,0x7A,0x2C,0x01,0x91,0x93,0x3F,
3181 0x88,0x39,0x10,0xF1,0x91,0x8B,0x48,0x0A,0x12,0xE3,0xA8,0x18,0x28,0x92,0x97,0x98,
3182 0x99,0x19,0xA1,0x11,0xB6,0x88,0x3B,0x10,0xD3,0xC3,0xA1,0x2A,0x8A,0x49,0x04,0xF1,
3183 0x91,0x02,0x8A,0x89,0x04,0xF1,0x98,0x80,0x18,0x12,0xE3,0x81,0x98,0x80,0x01,0xB3,
3184 0xF2,0x99,0x12,0x2A,0xB5,0xB3,0x92,0xAA,0x19,0x50,0xB2,0xC3,0x92,0xD0,0x2B,0x68,
3185 0x93,0x99,0xC0,0x2C,0x3E,0x80,0x20,0x08,0x93,0x0D,0x2A,0x31,0x8D,0x02,0x2B,0x91,
3186 0x08,0x0A,0x03,0x2C,0x3C,0x52,0xB9,0xA0,0x12,0xBF,0x3A,0x29,0x01,0x88,0xC0,0x6A,
3187 0x3C,0x0A,0x49,0x18,0x0B,0x39,0x2B,0x69,0x0A,0x84,0x2A,0x2A,0x1C,0x2A,0xC3,0x8C,
3188 0x19,0x50,0x09,0x91,0xA7,0x8D,0x18,0x1A,0x28,0x00,0xA0,0x94,0x10,0x1F,0x20,0x90,
3189 0x8A,0x12,0xD0,0x1A,0x5A,0x81,0x04,0xBC,0x23,0x10,0xE0,0x90,0x90,0x18,0x1A,0xA6,
3190 0x12,0xB1,0xD0,0x4A,0x08,0x82,0x92,0xB6,0x9A,0x0A,0x12,0x88,0xC3,0xC5,0x8A,0x89,
3191 0x20,0xB5,0x93,0x0B,0x18,0x00,0x09,0xF2,0x88,0x2A,0x4A,0x08,0x05,0xB2,0xA9,0x3B,
3192 0x5D,0x28,0xA4,0xB1,0x00,0x19,0x19,0x7A,0xA3,0xB3,0x0A,0x90,0xA1,0xC4,0x80,0xBA,
3193 0x50,0x13,0xC1,0xC2,0x9A,0x2A,0x7B,0x28,0x84,0xC1,0x09,0x3B,0x4E,0x20,0x91,0xA1,
3194 0x18,0xAB,0x79,0x10,0xB4,0x08,0x9A,0x11,0x2B,0xF0,0x93,0xAA,0x01,0x6A,0x01,0x93,
3195 0x80,0xB8,0x2A,0x5B,0x10,0x80,0x89,0x4A,0x5B,0x92,0x15,0xB2,0xA0,0x2F,0x19,0x93,
3196 0xB8,0x95,0x80,0x1C,0x21,0xA9,0x02,0x0B,0xA0,0x5A,0x18,0x98,0x39,0x1B,0x68,0x00,
3197 0x91,0x91,0x9C,0x39,0x3E,0x18,0x84,0xB3,0x9B,0x7A,0x08,0x18,0x0A,0xB5,0x91,0x0B,
3198 0x28,0x39,0x19,0x90,0x0A,0x50,0xAC,0x11,0x01,0xAB,0x88,0x52,0x1B,0x83,0xC4,0xA2,
3199 0x9A,0xAB,0x03,0x90,0x19,0x93,0x81,0x08,0x92,0x9A,0x68,0x98,0x19,0x39,0xC1,0x92,
3200 0x8A,0x38,0x4E,0x02,0xB1,0x90,0xC3,0x18,0x2B,0x04,0xC3,0xD2,0x91,0x90,0x81,0x89,
3201 0x13,0xF1,0x88,0x93,0xA2,0x00,0x91,0xC0,0x5B,0x21,0x99,0x93,0x06,0x9A,0x1B,0x48,
3202 0x99,0xB7,0x90,0x89,0x18,0x1B,0x11,0xA4,0xB2,0x81,0x9A,0x08,0x97,0x98,0x91,0x10,
3203 0xB8,0x06,0xA2,0xA0,0x29,0x2B,0x21,0xC2,0xD1,0x10,0x1A,0x4A,0x29,0xF1,0x98,0x29,
3204 0x1B,0x31,0x10,0xA0,0xA1,0x1D,0x5A,0x29,0xB2,0x82,0xA8,0x0F,0x28,0x21,0x09,0x91,
3205 0x82,0x4D,0x10,0xA3,0xB0,0x89,0x4C,0x39,0xA0,0xA4,0xA1,0x89,0x1E,0x28,0x29,0xA3,
3206 0xC3,0x2D,0x19,0x01,0x49,0x01,0x9B,0x0C,0x21,0xC2,0xA2,0x93,0x7C,0x2A,0x10,0x90,
3207
3208 /* Source: 08HH.ROM */
3209 /* Length: 384 / 0x00000180 */
3210
3211 0x75,0xF2,0xAB,0x7D,0x7E,0x5C,0x3B,0x4B,0x3C,0x4D,0x4A,0x02,0xB3,0xC5,0xE7,0xE3,
3212 0x92,0xB3,0xC4,0xB3,0xC3,0x8A,0x3B,0x5D,0x5C,0x3A,0x84,0xC2,0x91,0xA4,0xE7,0xF7,
3213 0xF7,0xF4,0xA1,0x1B,0x49,0xA5,0xB1,0x1E,0x7F,0x5A,0x00,0x89,0x39,0xB7,0xA8,0x3D,
3214 0x4A,0x84,0xE7,0xF7,0xE2,0x2D,0x4C,0x3A,0x4E,0x7D,0x04,0xB0,0x2D,0x4B,0x10,0x80,
3215 0xA3,0x99,0x10,0x0E,0x59,0x93,0xC4,0xB1,0x81,0xC4,0xA2,0xB2,0x88,0x08,0x3F,0x3B,
3216 0x28,0xA6,0xC3,0xA2,0xA2,0xC5,0xC1,0x3F,0x7E,0x39,0x81,0x93,0xC2,0xA3,0xE5,0xD2,
3217 0x80,0x93,0xB8,0x6D,0x49,0x82,0xD4,0xA1,0x90,0x01,0xA0,0x09,0x04,0xE3,0xB2,0x91,
3218 0xB7,0xB3,0xA8,0x2A,0x03,0xF3,0xA1,0x92,0xC5,0xC3,0xB2,0x0B,0x30,0xB3,0x8E,0x6D,
3219 0x4A,0x01,0xB4,0xB4,0xC4,0xC3,0x99,0x3B,0x12,0xE3,0xA1,0x88,0x82,0xB4,0x9A,0x5C,
3220 0x3A,0x18,0x93,0xC3,0xB3,0xB4,0xA8,0x19,0x04,0xF3,0xA8,0x3B,0x10,0xA2,0x88,0xA5,
3221 0xB2,0x0B,0x6D,0x4B,0x10,0x91,0x89,0x3C,0x18,0x18,0xA6,0xC4,0xC3,0x98,0x19,0x2B,
3222 0x20,0x91,0xA0,0x4E,0x28,0x93,0xB3,0xC2,0x92,0xA9,0x5A,0x96,0xC4,0xC2,0x09,0x01,
3223 0xC4,0xA1,0x92,0xC4,0xA1,0x89,0x10,0xA3,0xA1,0x90,0x1C,0x5A,0x01,0xC5,0xA1,0x92,
3224 0xD4,0xB3,0xC4,0xC4,0xC3,0xA1,0x88,0x1A,0x28,0x89,0x3C,0x3A,0x3D,0x29,0x00,0x93,
3225 0xB0,0x3D,0x28,0x80,0x91,0x82,0xE3,0x99,0x2A,0x11,0xD6,0xC3,0x99,0x29,0x82,0xC4,
3226 0xC3,0xA1,0x0A,0x3B,0x3D,0x3A,0x02,0xC3,0xA2,0x99,0x3B,0x2C,0x7C,0x28,0x81,0xA3,
3227 0xB2,0xA3,0xB1,0x08,0x1A,0x3C,0x18,0x2E,0x4C,0x39,0xA5,0xB3,0xB4,0xC2,0x88,0x08,
3228 0x19,0x0A,0x49,0xB7,0xB3,0xA2,0xA1,0x92,0xA1,0x93,0xB1,0x0C,0x7D,0x39,0x93,0xB3,
3229 0xB1,0x1A,0x19,0x5D,0x28,0xA6,0xC4,0xB2,0x90,0x09,0x2A,0x18,0x1B,0x5B,0x28,0x88,
3230 0x2C,0x29,0x82,0xA0,0x18,0x91,0x2D,0x29,0x2B,0x5C,0x4C,0x3B,0x4C,0x28,0x80,0x92,
3231 0x90,0x09,0x2B,0x28,0x1D,0x6B,0x11,0xC5,0xB2,0x0B,0x39,0x09,0x4D,0x28,0x88,0x00,
3232 0x1B,0x28,0x94,0xE3,0xA0,0x1A,0x28,0xB5,0xB4,0xB3,0xB2,0x93,0xE2,0x91,0x92,0xD4,
3233 0xA0,0x1B,0x4A,0x01,0xA1,0x88,0x2D,0x5C,0x3B,0x28,0x08,0x93,0xD4,0xB2,0x91,0xB4,
3234 0xA0,0x3E,0x3B,0x4B,0x3B,0x29,0x08,0x93,0x9B,0x7B,0x3A,0x19,0x00,0x80,0x80,0xA0,
3235
3236 /* Source: 10TOM.ROM */
3237 /* Length: 640 / 0x00000280 */
3238
3239 0x77,0x27,0x87,0x01,0x2D,0x4F,0xC3,0xC1,0x92,0x91,0x89,0x59,0x83,0x1A,0x32,0xC2,
3240 0x95,0xB1,0x81,0x88,0x81,0x4A,0x3D,0x11,0x9E,0x0B,0x88,0x0C,0x18,0x3B,0x11,0x11,
3241 0x91,0x00,0xA0,0xE2,0x0A,0x48,0x13,0x24,0x81,0x48,0x1B,0x39,0x1C,0x83,0x84,0xA1,
3242 0xD1,0x8E,0x8A,0x0B,0xC0,0x98,0x92,0xB8,0x39,0x90,0x10,0x92,0xF0,0xB5,0x88,0x32,
3243 0x49,0x51,0x21,0x03,0x82,0x10,0x8A,0x7A,0x09,0x00,0xA2,0xCA,0x1B,0xCC,0x1C,0xB9,
3244 0x8E,0x89,0x89,0xA1,0x89,0x92,0x29,0x11,0x60,0x40,0x14,0x22,0x32,0x78,0x40,0x01,
3245 0x02,0x90,0x81,0xAB,0x0B,0x00,0xAF,0x99,0xCC,0xAB,0xDA,0xA9,0x99,0x1B,0x30,0x14,
3246 0x92,0x22,0x19,0x68,0x32,0x14,0x26,0x13,0x23,0x23,0x20,0x12,0x9A,0xA8,0xB9,0xFA,
3247 0xAA,0xCA,0xCC,0x0C,0xA8,0xAE,0x88,0xB9,0x88,0xA0,0x02,0x21,0x50,0x43,0x03,0x81,
3248 0x2A,0x11,0x34,0x63,0x24,0x33,0x22,0x38,0x8B,0xEA,0xAE,0x99,0xA0,0x90,0x82,0x00,
3249 0x89,0xBF,0x8A,0xE8,0xA9,0x90,0x01,0x12,0x13,0x12,0x08,0xA9,0xAA,0xC9,0x22,0x63,
3250 0x63,0x12,0x44,0x00,0x10,0x88,0x9C,0x98,0xA1,0x85,0x03,0x32,0x36,0x80,0x89,0xDB,
3251 0xDB,0xBB,0xB9,0xBA,0x01,0x81,0x28,0x19,0xCB,0xFA,0xBC,0x09,0x13,0x37,0x34,0x34,
3252 0x23,0x31,0x20,0x10,0x00,0x00,0x28,0x38,0x10,0x88,0xEC,0x8D,0xCB,0xBC,0xCC,0xBB,
3253 0xBB,0xC9,0x99,0x00,0x00,0x33,0x11,0x22,0x81,0x07,0x41,0x54,0x34,0x34,0x22,0x31,
3254 0x00,0x88,0x9A,0x9B,0x98,0xAB,0x8E,0x9B,0xBD,0x9C,0xBC,0xBB,0xDA,0xAA,0xA9,0x99,
3255 0x18,0x38,0x60,0x20,0x31,0x13,0x13,0x51,0x14,0x31,0x53,0x33,0x35,0x22,0x01,0x8A,
3256 0x9C,0xA9,0xCA,0xC9,0xA8,0x00,0x10,0x81,0x9C,0x9E,0xAB,0xCC,0xAB,0xBA,0x98,0x30,
3257 0x52,0x03,0x81,0x08,0x9C,0xAC,0xAC,0x18,0x11,0x03,0x51,0x61,0x41,0x31,0x31,0x02,
3258 0x01,0x20,0x24,0x43,0x44,0x40,0x30,0x10,0xBC,0xBE,0xCB,0xDB,0xAB,0xBA,0x99,0x98,
3259 0x99,0xAA,0xBD,0xAA,0xC8,0x90,0x11,0x53,0x37,0x23,0x43,0x34,0x33,0x33,0x33,0x11,
3260 0x28,0x00,0x19,0xA9,0x9A,0xCB,0xCE,0xBB,0xEB,0xBC,0xBB,0xCA,0xBA,0xA8,0x88,0x11,
3261 0x12,0x21,0x20,0x22,0x26,0x26,0x23,0x23,0x43,0x24,0x22,0x32,0x20,0x31,0x81,0x9A,
3262 0xBC,0xBC,0xCB,0xBD,0x9A,0xA9,0x90,0x98,0xBA,0xCC,0xCB,0xBC,0x8B,0x88,0x22,0x35,
3263 0x23,0x12,0x99,0x8B,0xAA,0xAA,0x89,0x82,0x93,0x31,0x42,0x23,0x23,0x21,0x32,0x11,
3264 0x20,0x13,0x13,0x24,0x24,0x24,0x22,0x11,0x8A,0x9E,0xAC,0xAC,0xAA,0xBA,0xAA,0xAB,
3265 0xBD,0xBC,0xCB,0xCB,0xA9,0xA8,0x91,0x12,0x44,0x43,0x44,0x34,0x34,0x42,0x33,0x42,
3266 0x21,0x11,0x11,0x88,0x80,0xAA,0x0B,0xAC,0xCB,0xEC,0xAC,0xBA,0xCA,0xAB,0x9A,0x99,
3267 0x80,0x91,0x09,0x08,0x10,0x22,0x44,0x43,0x44,0x33,0x43,0x22,0x13,0x21,0x22,0x20,
3268 0x09,0x88,0xB9,0xC8,0xBB,0xAB,0xAB,0xA9,0xA9,0x9B,0x9B,0x99,0x90,0x90,0x00,0x81,
3269 0x00,0x08,0x09,0x8A,0x9A,0xAA,0xA9,0xA9,0x99,0x90,0x80,0x01,0x80,0x00,0x09,0x31,
3270 0x32,0x44,0x33,0x43,0x34,0x33,0x24,0x22,0x23,0x12,0x10,0x09,0x9B,0xAB,0xCA,0xCC,
3271 0xBB,0xCB,0xDA,0xCA,0xAB,0xCA,0xAB,0xA9,0xA8,0x92,0x12,0x43,0x53,0x35,0x23,0x33,
3272 0x43,0x43,0x52,0x22,0x22,0x21,0x01,0x09,0x89,0xA9,0xBB,0xBD,0xBC,0xCB,0xDA,0xAB,
3273 0xAB,0xAB,0xAA,0xA9,0x99,0xA8,0x09,0x01,0x11,0x34,0x25,0x23,0x33,0x51,0x22,0x31,
3274 0x12,0x20,0x21,0x12,0x10,0x80,0x99,0x9A,0x99,0x99,0x88,0x08,0x00,0x88,0xA9,0x99,
3275 0x99,0x80,0x80,0x10,0x01,0x00,0x9A,0xAA,0xBB,0xBA,0xBA,0xA9,0x99,0x99,0x89,0x99,
3276 0x99,0x00,0x01,0x33,0x35,0x24,0x23,0x34,0x23,0x33,0x34,0x33,0x43,0x32,0x21,0x88,
3277 0xAB,0xBD,0xBB,0xDB,0xAB,0xBA,0xBB,0xDA,0xBB,0xCB,0xBB,0xBC,0xA8,0x90,0x01,0x12,
3278 0x23,0x43,0x53,0x34,0x34,0x39,0x80,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,
3279
3280 /* Source: 20RIM.ROM */
3281 /* Length: 128 / 0x00000080 */
3282
3283 0x0F,0xFF,0x73,0x8E,0x71,0xCD,0x00,0x49,0x10,0x90,0x21,0x49,0xA0,0xDB,0x02,0x3A,
3284 0xE3,0x0A,0x50,0x98,0xC0,0x59,0xA2,0x99,0x09,0x22,0xA2,0x80,0x10,0xA8,0x5B,0xD2,
3285 0x88,0x21,0x09,0x96,0xA8,0x10,0x0A,0xE0,0x08,0x48,0x19,0xAB,0x52,0xA8,0x92,0x0C,
3286 0x03,0x19,0xE2,0x0A,0x12,0xC2,0x81,0x1E,0x01,0xD0,0x48,0x88,0x98,0x01,0x49,0x91,
3287 0xAA,0x2C,0x25,0x89,0x88,0xB5,0x81,0xA2,0x9A,0x12,0x9E,0x38,0x3B,0x81,0x9B,0x59,
3288 0x01,0x93,0xCA,0x4A,0x21,0xA0,0x3D,0x0A,0x39,0x3D,0x12,0xA8,0x3F,0x18,0x01,0x92,
3289 0x1C,0x00,0xB2,0x48,0xB9,0x94,0xA3,0x19,0x4F,0x19,0xB2,0x32,0x90,0xBA,0x01,0xE6,
3290 0x91,0x80,0xC1,0xA4,0x2A,0x08,0xA1,0xB1,0x25,0xD2,0x88,0x99,0x21,0x80,0x88,0x80,
3291 };
3292
3293
3294
3295 /* flag enable control 0x110 */
YM2608IRQFlagWrite(FM_OPN * OPN,YM2608 * F2608,int v)3296 INLINE void YM2608IRQFlagWrite(FM_OPN *OPN, YM2608 *F2608, int v)
3297 {
3298 if( v & 0x80 )
3299 { /* Reset IRQ flag */
3300 FM_STATUS_RESET(&OPN->ST, 0xf7); /* don't touch BUFRDY flag otherwise we'd have to call ymdeltat module to set the flag back */
3301 }
3302 else
3303 { /* Set status flag mask */
3304 F2608->flagmask = (~(v&0x1f));
3305 FM_IRQMASK_SET(&OPN->ST, (F2608->irqmask & F2608->flagmask) );
3306 }
3307 }
3308
3309 /* compatible mode & IRQ enable control 0x29 */
YM2608IRQMaskWrite(FM_OPN * OPN,YM2608 * F2608,int v)3310 INLINE void YM2608IRQMaskWrite(FM_OPN *OPN, YM2608 *F2608, int v)
3311 {
3312 /* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
3313
3314 /* extend 3ch. enable/disable */
3315 if(v&0x80)
3316 OPN->type |= TYPE_6CH; /* OPNA mode - 6 FM channels */
3317 else
3318 OPN->type &= ~TYPE_6CH; /* OPN mode - 3 FM channels */
3319
3320 /* IRQ MASK store and set */
3321 F2608->irqmask = v&0x1f;
3322 FM_IRQMASK_SET(&OPN->ST, (F2608->irqmask & F2608->flagmask) );
3323 }
3324
3325 /* Generate samples for one of the YM2608s */
ym2608_update_one(void * chip,FMSAMPLE ** buffer,int length)3326 void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length)
3327 {
3328 YM2608 *F2608 = (YM2608 *)chip;
3329 FM_OPN *OPN = &F2608->OPN;
3330 YM_DELTAT *DELTAT = &F2608->deltaT;
3331 int i,j;
3332 FMSAMPLE *bufL,*bufR;
3333 FM_CH *cch[6];
3334 INT32 *out_fm = OPN->out_fm;
3335
3336 /* set bufer */
3337 bufL = buffer[0];
3338 bufR = buffer[1];
3339
3340 cch[0] = &F2608->CH[0];
3341 cch[1] = &F2608->CH[1];
3342 cch[2] = &F2608->CH[2];
3343 cch[3] = &F2608->CH[3];
3344 cch[4] = &F2608->CH[4];
3345 cch[5] = &F2608->CH[5];
3346
3347 /* refresh PG and EG */
3348 refresh_fc_eg_chan( OPN, cch[0] );
3349 refresh_fc_eg_chan( OPN, cch[1] );
3350 if( (OPN->ST.mode & 0xc0) )
3351 {
3352 /* 3SLOT MODE */
3353 if( cch[2]->SLOT[SLOT1].Incr==-1)
3354 {
3355 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
3356 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
3357 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
3358 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
3359 }
3360 }
3361 else
3362 refresh_fc_eg_chan( OPN, cch[2] );
3363 refresh_fc_eg_chan( OPN, cch[3] );
3364 refresh_fc_eg_chan( OPN, cch[4] );
3365 refresh_fc_eg_chan( OPN, cch[5] );
3366
3367
3368 /* buffering */
3369 for(i=0; i < length ; i++)
3370 {
3371
3372 advance_lfo(OPN);
3373
3374 /* clear output acc. */
3375 OPN->out_adpcm[OUTD_LEFT] = OPN->out_adpcm[OUTD_RIGHT] = OPN->out_adpcm[OUTD_CENTER] = 0;
3376 OPN->out_delta[OUTD_LEFT] = OPN->out_delta[OUTD_RIGHT] = OPN->out_delta[OUTD_CENTER] = 0;
3377 /* clear outputs */
3378 out_fm[0] = 0;
3379 out_fm[1] = 0;
3380 out_fm[2] = 0;
3381 out_fm[3] = 0;
3382 out_fm[4] = 0;
3383 out_fm[5] = 0;
3384
3385 /* calculate FM */
3386 chan_calc(OPN, cch[0], 0 );
3387 chan_calc(OPN, cch[1], 1 );
3388 chan_calc(OPN, cch[2], 2 );
3389 chan_calc(OPN, cch[3], 3 );
3390 chan_calc(OPN, cch[4], 4 );
3391 chan_calc(OPN, cch[5], 5 );
3392
3393 /* deltaT ADPCM */
3394 if( DELTAT->portstate&0x80 && ! F2608->MuteDeltaT )
3395 YM_DELTAT_ADPCM_CALC(DELTAT);
3396
3397 /* ADPCMA */
3398 for( j = 0; j < 6; j++ )
3399 {
3400 if( F2608->adpcm[j].flag )
3401 ADPCMA_calc_chan( F2608, &F2608->adpcm[j]);
3402 }
3403
3404 /* advance envelope generator */
3405 OPN->eg_timer += OPN->eg_timer_add;
3406 while (OPN->eg_timer >= OPN->eg_timer_overflow)
3407 {
3408 OPN->eg_timer -= OPN->eg_timer_overflow;
3409 OPN->eg_cnt++;
3410
3411 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
3412 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
3413 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
3414 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
3415 advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]);
3416 advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]);
3417 }
3418
3419 /* buffering */
3420 {
3421 int lt,rt;
3422
3423 /*lt = OPN->out_adpcm[OUTD_LEFT] + OPN->out_adpcm[OUTD_CENTER];
3424 rt = OPN->out_adpcm[OUTD_RIGHT] + OPN->out_adpcm[OUTD_CENTER];
3425 lt += (OPN->out_delta[OUTD_LEFT] + OPN->out_delta[OUTD_CENTER])>>9;
3426 rt += (OPN->out_delta[OUTD_RIGHT] + OPN->out_delta[OUTD_CENTER])>>9;
3427 lt += ((out_fm[0]>>1) & OPN->pan[0]); // shift right verified on real YM2608
3428 rt += ((out_fm[0]>>1) & OPN->pan[1]);
3429 lt += ((out_fm[1]>>1) & OPN->pan[2]);
3430 rt += ((out_fm[1]>>1) & OPN->pan[3]);
3431 lt += ((out_fm[2]>>1) & OPN->pan[4]);
3432 rt += ((out_fm[2]>>1) & OPN->pan[5]);
3433 lt += ((out_fm[3]>>1) & OPN->pan[6]);
3434 rt += ((out_fm[3]>>1) & OPN->pan[7]);
3435 lt += ((out_fm[4]>>1) & OPN->pan[8]);
3436 rt += ((out_fm[4]>>1) & OPN->pan[9]);
3437 lt += ((out_fm[5]>>1) & OPN->pan[10]);
3438 rt += ((out_fm[5]>>1) & OPN->pan[11]);*/
3439 // this way it's louder (and more accurate)
3440 lt = (OPN->out_adpcm[OUTD_LEFT] + OPN->out_adpcm[OUTD_CENTER]) << 1;
3441 rt = (OPN->out_adpcm[OUTD_RIGHT] + OPN->out_adpcm[OUTD_CENTER]) << 1;
3442 lt += (OPN->out_delta[OUTD_LEFT] + OPN->out_delta[OUTD_CENTER])>>8;
3443 rt += (OPN->out_delta[OUTD_RIGHT] + OPN->out_delta[OUTD_CENTER])>>8;
3444 lt += (out_fm[0] & OPN->pan[0]);
3445 rt += (out_fm[0] & OPN->pan[1]);
3446 lt += (out_fm[1] & OPN->pan[2]);
3447 rt += (out_fm[1] & OPN->pan[3]);
3448 lt += (out_fm[2] & OPN->pan[4]);
3449 rt += (out_fm[2] & OPN->pan[5]);
3450 lt += (out_fm[3] & OPN->pan[6]);
3451 rt += (out_fm[3] & OPN->pan[7]);
3452 lt += (out_fm[4] & OPN->pan[8]);
3453 rt += (out_fm[4] & OPN->pan[9]);
3454 lt += (out_fm[5] & OPN->pan[10]);
3455 rt += (out_fm[5] & OPN->pan[11]);
3456
3457 lt >>= FINAL_SH;
3458 rt >>= FINAL_SH;
3459
3460 //Limit( lt, MAXOUT, MINOUT );
3461 //Limit( rt, MAXOUT, MINOUT );
3462 /* buffering */
3463 bufL[i] = lt;
3464 bufR[i] = rt;
3465
3466 #ifdef SAVE_SAMPLE
3467 SAVE_ALL_CHANNELS
3468 #endif
3469
3470 }
3471
3472 /* timer A control */
3473 INTERNAL_TIMER_A( &OPN->ST , cch[2] )
3474 }
3475 INTERNAL_TIMER_B(&OPN->ST,length)
3476
3477
3478 /* check IRQ for DELTA-T EOS */
3479 FM_STATUS_SET(&OPN->ST, 0);
3480
3481 }
3482
3483 #ifdef __STATE_H__
ym2608_postload(void * chip)3484 void ym2608_postload(void *chip)
3485 {
3486 if (chip)
3487 {
3488 YM2608 *F2608 = (YM2608 *)chip;
3489 int r;
3490
3491 /* prescaler */
3492 OPNPrescaler_w(&F2608->OPN,1,2);
3493 F2608->deltaT.freqbase = F2608->OPN.ST.freqbase;
3494 /* IRQ mask / mode */
3495 YM2608IRQMaskWrite(&F2608->OPN, F2608, F2608->REGS[0x29]);
3496 /* SSG registers */
3497 for(r=0;r<16;r++)
3498 {
3499 (*F2608->OPN.ST.SSG->write)(F2608->OPN.ST.param,0,r);
3500 (*F2608->OPN.ST.SSG->write)(F2608->OPN.ST.param,1,F2608->REGS[r]);
3501 }
3502
3503 /* OPN registers */
3504 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
3505 for(r=0x30;r<0x9e;r++)
3506 if((r&3) != 3)
3507 {
3508 OPNWriteReg(&F2608->OPN,r,F2608->REGS[r]);
3509 OPNWriteReg(&F2608->OPN,r|0x100,F2608->REGS[r|0x100]);
3510 }
3511 /* FB / CONNECT , L / R / AMS / PMS */
3512 for(r=0xb0;r<0xb6;r++)
3513 if((r&3) != 3)
3514 {
3515 OPNWriteReg(&F2608->OPN,r,F2608->REGS[r]);
3516 OPNWriteReg(&F2608->OPN,r|0x100,F2608->REGS[r|0x100]);
3517 }
3518 /* FM channels */
3519 /*FM_channel_postload(F2608->CH,6);*/
3520 /* rhythm(ADPCMA) */
3521 FM_ADPCMAWrite(F2608,1,F2608->REGS[0x111]);
3522 for( r=0x08 ; r<0x0c ; r++)
3523 FM_ADPCMAWrite(F2608,r,F2608->REGS[r+0x110]);
3524 /* Delta-T ADPCM unit */
3525 YM_DELTAT_postload(&F2608->deltaT , &F2608->REGS[0x100] );
3526 }
3527 }
3528
YM2608_save_state(YM2608 * F2608,const device_config * device)3529 static void YM2608_save_state(YM2608 *F2608, const device_config *device)
3530 {
3531 state_save_register_device_item_array(device, 0, F2608->REGS);
3532 FMsave_state_st(device,&F2608->OPN.ST);
3533 FMsave_state_channel(device,F2608->CH,6);
3534 /* 3slots */
3535 state_save_register_device_item_array(device, 0, F2608->OPN.SL3.fc);
3536 state_save_register_device_item(device, 0, F2608->OPN.SL3.fn_h);
3537 state_save_register_device_item_array(device, 0, F2608->OPN.SL3.kcode);
3538 /* address register1 */
3539 state_save_register_device_item(device, 0, F2608->addr_A1);
3540 /* rythm(ADPCMA) */
3541 FMsave_state_adpcma(device,F2608->adpcm);
3542 /* Delta-T ADPCM unit */
3543 YM_DELTAT_savestate(device,&F2608->deltaT);
3544 }
3545 #endif /* _STATE_H */
3546
YM2608_deltat_status_set(void * chip,UINT8 changebits)3547 static void YM2608_deltat_status_set(void *chip, UINT8 changebits)
3548 {
3549 YM2608 *F2608 = (YM2608 *)chip;
3550 FM_STATUS_SET(&(F2608->OPN.ST), changebits);
3551 }
YM2608_deltat_status_reset(void * chip,UINT8 changebits)3552 static void YM2608_deltat_status_reset(void *chip, UINT8 changebits)
3553 {
3554 YM2608 *F2608 = (YM2608 *)chip;
3555 FM_STATUS_RESET(&(F2608->OPN.ST), changebits);
3556 }
3557 /* YM2608(OPNA) */
3558 //void * ym2608_init(void *param, const device_config *device, int clock, int rate,
3559 // void *pcmrom,int pcmsize,
3560 // FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg)
ym2608_init(void * param,int clock,int rate,FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler,const ssg_callbacks * ssg)3561 void * ym2608_init(void *param, int clock, int rate,
3562 FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg)
3563 {
3564 YM2608 *F2608;
3565
3566 /* allocate extend state space */
3567 if( (F2608 = (YM2608 *)malloc(sizeof(YM2608)))==NULL)
3568 return NULL;
3569 /* clear */
3570 memset(F2608,0,sizeof(YM2608));
3571 /* allocate total level table (128kb space) */
3572 if( !init_tables() )
3573 {
3574 free( F2608 );
3575 return NULL;
3576 }
3577
3578 F2608->OPN.ST.param = param;
3579 F2608->OPN.type = TYPE_YM2608;
3580 F2608->OPN.P_CH = F2608->CH;
3581 //F2608->OPN.ST.device = device;
3582 F2608->OPN.ST.clock = clock;
3583 F2608->OPN.ST.rate = rate;
3584
3585 /* External handlers */
3586 F2608->OPN.ST.timer_handler = timer_handler;
3587 F2608->OPN.ST.IRQ_Handler = IRQHandler;
3588 F2608->OPN.ST.SSG = ssg;
3589
3590 /* DELTA-T */
3591 //F2608->deltaT.memory = (UINT8 *)pcmrom;
3592 //F2608->deltaT.memory_size = pcmsize;
3593 F2608->deltaT.memory = NULL;
3594 F2608->deltaT.memory_size = 0x00;
3595 F2608->deltaT.memory_mask = 0x00;
3596
3597 /*F2608->deltaT.write_time = 20.0 / clock;*/ /* a single byte write takes 20 cycles of main clock */
3598 /*F2608->deltaT.read_time = 18.0 / clock;*/ /* a single byte read takes 18 cycles of main clock */
3599
3600 F2608->deltaT.status_set_handler = YM2608_deltat_status_set;
3601 F2608->deltaT.status_reset_handler = YM2608_deltat_status_reset;
3602 F2608->deltaT.status_change_which_chip = F2608;
3603 F2608->deltaT.status_change_EOS_bit = 0x04; /* status flag: set bit2 on End Of Sample */
3604 F2608->deltaT.status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY */
3605 F2608->deltaT.status_change_ZERO_bit = 0x10; /* status flag: set bit4 if silence continues for more than 290 miliseconds while recording the ADPCM */
3606
3607 /* ADPCM Rhythm */
3608 F2608->pcmbuf = (UINT8*)YM2608_ADPCM_ROM;
3609 F2608->pcm_size = 0x2000;
3610
3611 Init_ADPCMATable();
3612
3613 #ifdef __STATE_H__
3614 YM2608_save_state(F2608, device);
3615 #endif
3616 return F2608;
3617 }
3618
3619 /* shut down emulator */
ym2608_shutdown(void * chip)3620 void ym2608_shutdown(void *chip)
3621 {
3622 YM2608 *F2608 = (YM2608 *)chip;
3623
3624 free(F2608->deltaT.memory); F2608->deltaT.memory = NULL;
3625
3626 FMCloseTable();
3627 free(F2608);
3628 }
3629
3630 /* reset one of chips */
ym2608_reset_chip(void * chip)3631 void ym2608_reset_chip(void *chip)
3632 {
3633 int i;
3634 YM2608 *F2608 = (YM2608 *)chip;
3635 FM_OPN *OPN = &F2608->OPN;
3636 YM_DELTAT *DELTAT = &F2608->deltaT;
3637
3638 /* Reset Prescaler */
3639 OPNPrescaler_w(OPN , 0 , 2);
3640 F2608->deltaT.freqbase = OPN->ST.freqbase;
3641 /* reset SSG section */
3642 (*OPN->ST.SSG->reset)(OPN->ST.param);
3643
3644 /* status clear */
3645 FM_BUSY_CLEAR(&OPN->ST);
3646
3647 /* register 0x29 - default value after reset is:
3648 enable only 3 FM channels and enable all the status flags */
3649 YM2608IRQMaskWrite(OPN, F2608, 0x1f ); /* default value for D4-D0 is 1 */
3650
3651 /* register 0x10, A1=1 - default value is 1 for D4, D3, D2, 0 for the rest */
3652 YM2608IRQFlagWrite(OPN, F2608, 0x1c ); /* default: enable timer A and B, disable EOS, BRDY and ZERO */
3653
3654 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
3655
3656 OPN->eg_timer = 0;
3657 OPN->eg_cnt = 0;
3658
3659 FM_STATUS_RESET(&OPN->ST, 0xff);
3660
3661 reset_channels( &OPN->ST , F2608->CH , 6 );
3662 /* reset OPerator paramater */
3663 for(i = 0xb6 ; i >= 0xb4 ; i-- )
3664 {
3665 OPNWriteReg(OPN,i ,0xc0);
3666 OPNWriteReg(OPN,i|0x100,0xc0);
3667 }
3668 for(i = 0xb2 ; i >= 0x30 ; i-- )
3669 {
3670 OPNWriteReg(OPN,i ,0);
3671 OPNWriteReg(OPN,i|0x100,0);
3672 }
3673 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
3674
3675 /* ADPCM - percussion sounds */
3676 for( i = 0; i < 6; i++ )
3677 {
3678 if (i<=3) /* channels 0,1,2,3 */
3679 F2608->adpcm[i].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2608->OPN.ST.freqbase)/3.0);
3680 else /* channels 4 and 5 work with slower clock */
3681 F2608->adpcm[i].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2608->OPN.ST.freqbase)/6.0);
3682
3683 F2608->adpcm[i].start = YM2608_ADPCM_ROM_addr[i*2];
3684 F2608->adpcm[i].end = YM2608_ADPCM_ROM_addr[i*2+1];
3685
3686 F2608->adpcm[i].now_addr = 0;
3687 F2608->adpcm[i].now_step = 0;
3688 /* F2608->adpcm[i].delta = 21866; */
3689 F2608->adpcm[i].vol_mul = 0;
3690 F2608->adpcm[i].pan = &OPN->out_adpcm[OUTD_CENTER]; /* default center */
3691 F2608->adpcm[i].flagMask = 0;
3692 F2608->adpcm[i].flag = 0;
3693 F2608->adpcm[i].adpcm_acc = 0;
3694 F2608->adpcm[i].adpcm_step= 0;
3695 F2608->adpcm[i].adpcm_out = 0;
3696 }
3697 F2608->adpcmTL = 0x3f;
3698
3699 F2608->adpcm_arrivedEndAddress = 0; /* not used */
3700
3701 /* DELTA-T unit */
3702 DELTAT->freqbase = OPN->ST.freqbase;
3703 DELTAT->output_pointer = OPN->out_delta;
3704 DELTAT->portshift = 5; /* always 5bits shift */ /* ASG */
3705 DELTAT->output_range = 1<<23;
3706 YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER,YM_DELTAT_EMULATION_MODE_NORMAL);
3707 }
3708
3709 /* YM2608 write */
3710 /* n = number */
3711 /* a = address */
3712 /* v = value */
ym2608_write(void * chip,int a,UINT8 v)3713 int ym2608_write(void *chip, int a,UINT8 v)
3714 {
3715 YM2608 *F2608 = (YM2608 *)chip;
3716 FM_OPN *OPN = &F2608->OPN;
3717 int addr;
3718
3719 v &= 0xff; /*adjust to 8 bit bus */
3720
3721
3722 switch(a&3)
3723 {
3724 case 0: /* address port 0 */
3725 OPN->ST.address = v;
3726 F2608->addr_A1 = 0;
3727
3728 /* Write register to SSG emulator */
3729 if( v < 16 ) (*OPN->ST.SSG->write)(OPN->ST.param,0,v);
3730 /* prescaler selecter : 2d,2e,2f */
3731 if( v >= 0x2d && v <= 0x2f )
3732 {
3733 OPNPrescaler_w(OPN , v , 2);
3734 //TODO: set ADPCM[c].step
3735 F2608->deltaT.freqbase = OPN->ST.freqbase;
3736 }
3737 break;
3738
3739 case 1: /* data port 0 */
3740 if (F2608->addr_A1 != 0)
3741 break; /* verified on real YM2608 */
3742
3743 addr = OPN->ST.address;
3744 F2608->REGS[addr] = v;
3745 switch(addr & 0xf0)
3746 {
3747 case 0x00: /* SSG section */
3748 /* Write data to SSG emulator */
3749 (*OPN->ST.SSG->write)(OPN->ST.param,a,v);
3750 break;
3751 case 0x10: /* 0x10-0x1f : Rhythm section */
3752 ym2608_update_req(OPN->ST.param);
3753 FM_ADPCMAWrite(F2608,addr-0x10,v);
3754 break;
3755 case 0x20: /* Mode Register */
3756 switch(addr)
3757 {
3758 case 0x29: /* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
3759 YM2608IRQMaskWrite(OPN, F2608, v);
3760 break;
3761 default:
3762 ym2608_update_req(OPN->ST.param);
3763 OPNWriteMode(OPN,addr,v);
3764 }
3765 break;
3766 default: /* OPN section */
3767 ym2608_update_req(OPN->ST.param);
3768 OPNWriteReg(OPN,addr,v);
3769 }
3770 break;
3771
3772 case 2: /* address port 1 */
3773 OPN->ST.address = v;
3774 F2608->addr_A1 = 1;
3775 break;
3776
3777 case 3: /* data port 1 */
3778 if (F2608->addr_A1 != 1)
3779 break; /* verified on real YM2608 */
3780
3781 addr = OPN->ST.address;
3782 F2608->REGS[addr | 0x100] = v;
3783 ym2608_update_req(OPN->ST.param);
3784 switch( addr & 0xf0 )
3785 {
3786 case 0x00: /* DELTAT PORT */
3787 switch( addr )
3788 {
3789 case 0x0e: /* DAC data */
3790 #ifdef _DEBUG
3791 logerror("YM2608: write to DAC data (unimplemented) value=%02x\n",v);
3792 #endif
3793 break;
3794 default:
3795 /* 0x00-0x0d */
3796 YM_DELTAT_ADPCM_Write(&F2608->deltaT,addr,v);
3797 }
3798 break;
3799 case 0x10: /* IRQ Flag control */
3800 if( addr == 0x10 )
3801 {
3802 YM2608IRQFlagWrite(OPN, F2608, v);
3803 }
3804 break;
3805 default:
3806 OPNWriteReg(OPN,addr | 0x100,v);
3807 }
3808 }
3809 return OPN->ST.irq;
3810 }
3811
ym2608_read(void * chip,int a)3812 UINT8 ym2608_read(void *chip,int a)
3813 {
3814 YM2608 *F2608 = (YM2608 *)chip;
3815 int addr = F2608->OPN.ST.address;
3816 UINT8 ret = 0;
3817
3818 switch( a&3 )
3819 {
3820 case 0: /* status 0 : YM2203 compatible */
3821 /* BUSY:x:x:x:x:x:FLAGB:FLAGA */
3822 ret = FM_STATUS_FLAG(&F2608->OPN.ST) & 0x83;
3823 break;
3824
3825 case 1: /* status 0, ID */
3826 if( addr < 16 ) ret = (*F2608->OPN.ST.SSG->read)(F2608->OPN.ST.param);
3827 else if(addr == 0xff) ret = 0x01; /* ID code */
3828 break;
3829
3830 case 2: /* status 1 : status 0 + ADPCM status */
3831 /* BUSY : x : PCMBUSY : ZERO : BRDY : EOS : FLAGB : FLAGA */
3832 ret = (FM_STATUS_FLAG(&F2608->OPN.ST) & (F2608->flagmask|0x80)) | ((F2608->deltaT.PCM_BSY & 1)<<5) ;
3833 break;
3834
3835 case 3:
3836 if(addr == 0x08)
3837 {
3838 ret = YM_DELTAT_ADPCM_Read(&F2608->deltaT);
3839 }
3840 else
3841 {
3842 if(addr == 0x0f)
3843 {
3844 #ifdef _DEBUG
3845 logerror("YM2608 A/D convertion is accessed but not implemented !\n");
3846 #endif
3847 ret = 0x80; /* 2's complement PCM data - result from A/D convertion */
3848 }
3849 }
3850 break;
3851 }
3852 return ret;
3853 }
3854
ym2608_timer_over(void * chip,int c)3855 int ym2608_timer_over(void *chip,int c)
3856 {
3857 YM2608 *F2608 = (YM2608 *)chip;
3858
3859 switch(c)
3860 {
3861 #if 0
3862 case 2:
3863 { /* BUFRDY flag */
3864 YM_DELTAT_BRDY_callback( &F2608->deltaT );
3865 }
3866 break;
3867 #endif
3868 case 1:
3869 { /* Timer B */
3870 TimerBOver( &(F2608->OPN.ST) );
3871 }
3872 break;
3873 case 0:
3874 { /* Timer A */
3875 ym2608_update_req(F2608->OPN.ST.param);
3876 /* timer update */
3877 TimerAOver( &(F2608->OPN.ST) );
3878 /* CSM mode key,TL controll */
3879 if( F2608->OPN.ST.mode & 0x80 )
3880 { /* CSM mode total level latch and auto key on */
3881 CSMKeyControll( F2608->OPN.type, &(F2608->CH[2]) );
3882 }
3883 }
3884 break;
3885 default:
3886 break;
3887 }
3888
3889 return F2608->OPN.ST.irq;
3890 }
3891
ym2608_write_pcmrom(void * chip,UINT8 rom_id,offs_t ROMSize,offs_t DataStart,offs_t DataLength,const UINT8 * ROMData)3892 void ym2608_write_pcmrom(void *chip, UINT8 rom_id, offs_t ROMSize, offs_t DataStart,
3893 offs_t DataLength, const UINT8* ROMData)
3894 {
3895 YM2608 *F2608 = (YM2608 *)chip;
3896
3897 switch(rom_id)
3898 {
3899 case 0x01: // ADPCM
3900 // unused, it's constant
3901 break;
3902 case 0x02: // DELTA-T
3903 if (F2608->deltaT.memory_size != ROMSize)
3904 {
3905 F2608->deltaT.memory = (UINT8*)realloc(F2608->deltaT.memory, ROMSize);
3906 F2608->deltaT.memory_size = ROMSize;
3907 memset(F2608->deltaT.memory, 0xFF, ROMSize);
3908 YM_DELTAT_calc_mem_mask(&F2608->deltaT);
3909 }
3910 if (DataStart > ROMSize)
3911 return;
3912 if (DataStart + DataLength > ROMSize)
3913 DataLength = ROMSize - DataStart;
3914
3915 memcpy(F2608->deltaT.memory + DataStart, ROMData, DataLength);
3916 break;
3917 }
3918
3919 return;
3920 }
3921
ym2608_set_mutemask(void * chip,UINT32 MuteMask)3922 void ym2608_set_mutemask(void *chip, UINT32 MuteMask)
3923 {
3924 YM2608 *F2608 = (YM2608 *)chip;
3925 UINT8 CurChn;
3926
3927 for (CurChn = 0; CurChn < 6; CurChn ++)
3928 F2608->CH[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
3929 for (CurChn = 0; CurChn < 6; CurChn ++)
3930 F2608->adpcm[CurChn].Muted = (MuteMask >> (CurChn + 6)) & 0x01;
3931 F2608->MuteDeltaT = (MuteMask >> 12) & 0x01;
3932
3933 return;
3934 }
3935 #endif /* BUILD_YM2608 */
3936
3937
3938
3939 #if (BUILD_YM2610||BUILD_YM2610B)
3940 /* YM2610(OPNB) */
3941
3942 /* Generate samples for one of the YM2610s */
ym2610_update_one(void * chip,FMSAMPLE ** buffer,int length)3943 void ym2610_update_one(void *chip, FMSAMPLE **buffer, int length)
3944 {
3945 YM2610 *F2610 = (YM2610 *)chip;
3946 FM_OPN *OPN = &F2610->OPN;
3947 YM_DELTAT *DELTAT = &F2610->deltaT;
3948 int i,j;
3949 FMSAMPLE *bufL,*bufR;
3950 FM_CH *cch[4];
3951 INT32 *out_fm = OPN->out_fm;
3952
3953 /* buffer setup */
3954 bufL = buffer[0];
3955 bufR = buffer[1];
3956
3957 cch[0] = &F2610->CH[1];
3958 cch[1] = &F2610->CH[2];
3959 cch[2] = &F2610->CH[4];
3960 cch[3] = &F2610->CH[5];
3961
3962 #ifdef YM2610B_WARNING
3963 #define FM_KEY_IS(SLOT) ((SLOT)->key)
3964 #define FM_MSG_YM2610B "YM2610-%p.CH%d is playing,Check whether the type of the chip is YM2610B\n"
3965 /* Check YM2610B warning message */
3966 if( FM_KEY_IS(&F2610->CH[0].SLOT[3]) )
3967 {
3968 LOG(LOG_WAR,(FM_MSG_YM2610B,F2610->OPN.ST.param,0));
3969 FM_KEY_IS(&F2610->CH[0].SLOT[3]) = 0;
3970 }
3971 if( FM_KEY_IS(&F2610->CH[3].SLOT[3]) )
3972 {
3973 LOG(LOG_WAR,(FM_MSG_YM2610B,F2610->OPN.ST.param,3));
3974 FM_KEY_IS(&F2610->CH[3].SLOT[3]) = 0;
3975 }
3976 #endif
3977
3978 /* refresh PG and EG */
3979 refresh_fc_eg_chan( OPN, cch[0] );
3980 if( (OPN->ST.mode & 0xc0) )
3981 {
3982 /* 3SLOT MODE */
3983 if( cch[1]->SLOT[SLOT1].Incr==-1)
3984 {
3985 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
3986 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
3987 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
3988 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT4] , cch[1]->fc , cch[1]->kcode );
3989 }
3990 }
3991 else
3992 refresh_fc_eg_chan( OPN, cch[1] );
3993 refresh_fc_eg_chan( OPN, cch[2] );
3994 refresh_fc_eg_chan( OPN, cch[3] );
3995
3996 /* buffering */
3997 for(i=0; i < length ; i++)
3998 {
3999
4000 advance_lfo(OPN);
4001
4002 /* clear output acc. */
4003 OPN->out_adpcm[OUTD_LEFT] = OPN->out_adpcm[OUTD_RIGHT] = OPN->out_adpcm[OUTD_CENTER] = 0;
4004 OPN->out_delta[OUTD_LEFT] = OPN->out_delta[OUTD_RIGHT] = OPN->out_delta[OUTD_CENTER] = 0;
4005 /* clear outputs */
4006 out_fm[1] = 0;
4007 out_fm[2] = 0;
4008 out_fm[4] = 0;
4009 out_fm[5] = 0;
4010
4011 /* advance envelope generator */
4012 OPN->eg_timer += OPN->eg_timer_add;
4013 while (OPN->eg_timer >= OPN->eg_timer_overflow)
4014 {
4015 OPN->eg_timer -= OPN->eg_timer_overflow;
4016 OPN->eg_cnt++;
4017
4018 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
4019 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
4020 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
4021 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
4022 }
4023
4024 /* calculate FM */
4025 chan_calc(OPN, cch[0], 1 ); /*remapped to 1*/
4026 chan_calc(OPN, cch[1], 2 ); /*remapped to 2*/
4027 chan_calc(OPN, cch[2], 4 ); /*remapped to 4*/
4028 chan_calc(OPN, cch[3], 5 ); /*remapped to 5*/
4029
4030 /* deltaT ADPCM */
4031 if( DELTAT->portstate&0x80 && ! F2610->MuteDeltaT )
4032 YM_DELTAT_ADPCM_CALC(DELTAT);
4033
4034 /* ADPCMA */
4035 for( j = 0; j < 6; j++ )
4036 {
4037 if( F2610->adpcm[j].flag )
4038 ADPCMA_calc_chan( F2610, &F2610->adpcm[j]);
4039 }
4040
4041 /* buffering */
4042 {
4043 int lt,rt;
4044
4045 /*lt = OPN->out_adpcm[OUTD_LEFT] + OPN->out_adpcm[OUTD_CENTER];
4046 rt = OPN->out_adpcm[OUTD_RIGHT] + OPN->out_adpcm[OUTD_CENTER];
4047 lt += (OPN->out_delta[OUTD_LEFT] + OPN->out_delta[OUTD_CENTER])>>9;
4048 rt += (OPN->out_delta[OUTD_RIGHT] + OPN->out_delta[OUTD_CENTER])>>9;
4049
4050
4051 lt += ((out_fm[1]>>1) & OPN->pan[2]); // the shift right was verified on real chip
4052 rt += ((out_fm[1]>>1) & OPN->pan[3]);
4053 lt += ((out_fm[2]>>1) & OPN->pan[4]);
4054 rt += ((out_fm[2]>>1) & OPN->pan[5]);
4055
4056 lt += ((out_fm[4]>>1) & OPN->pan[8]);
4057 rt += ((out_fm[4]>>1) & OPN->pan[9]);
4058 lt += ((out_fm[5]>>1) & OPN->pan[10]);
4059 rt += ((out_fm[5]>>1) & OPN->pan[11]);*/
4060
4061 lt = (OPN->out_adpcm[OUTD_LEFT] + OPN->out_adpcm[OUTD_CENTER]) << 1;
4062 rt = (OPN->out_adpcm[OUTD_RIGHT] + OPN->out_adpcm[OUTD_CENTER]) << 1;
4063 lt += (OPN->out_delta[OUTD_LEFT] + OPN->out_delta[OUTD_CENTER])>>8;
4064 rt += (OPN->out_delta[OUTD_RIGHT] + OPN->out_delta[OUTD_CENTER])>>8;
4065
4066
4067 lt += (out_fm[1] & OPN->pan[2]);
4068 rt += (out_fm[1] & OPN->pan[3]);
4069 lt += (out_fm[2] & OPN->pan[4]);
4070 rt += (out_fm[2] & OPN->pan[5]);
4071
4072 lt += (out_fm[4] & OPN->pan[8]);
4073 rt += (out_fm[4] & OPN->pan[9]);
4074 lt += (out_fm[5] & OPN->pan[10]);
4075 rt += (out_fm[5] & OPN->pan[11]);
4076
4077
4078 lt >>= FINAL_SH;
4079 rt >>= FINAL_SH;
4080
4081 //Limit( lt, MAXOUT, MINOUT );
4082 //Limit( rt, MAXOUT, MINOUT );
4083
4084 #ifdef SAVE_SAMPLE
4085 SAVE_ALL_CHANNELS
4086 #endif
4087
4088 /* buffering */
4089 bufL[i] = lt;
4090 bufR[i] = rt;
4091 }
4092
4093 /* timer A control */
4094 INTERNAL_TIMER_A( &OPN->ST , cch[1] )
4095 }
4096 INTERNAL_TIMER_B(&OPN->ST,length)
4097
4098 }
4099
4100 #if BUILD_YM2610B
4101 /* Generate samples for one of the YM2610Bs */
ym2610b_update_one(void * chip,FMSAMPLE ** buffer,int length)4102 void ym2610b_update_one(void *chip, FMSAMPLE **buffer, int length)
4103 {
4104 YM2610 *F2610 = (YM2610 *)chip;
4105 FM_OPN *OPN = &F2610->OPN;
4106 YM_DELTAT *DELTAT = &F2610->deltaT;
4107 int i,j;
4108 FMSAMPLE *bufL,*bufR;
4109 FM_CH *cch[6];
4110 INT32 *out_fm = OPN->out_fm;
4111
4112 /* buffer setup */
4113 bufL = buffer[0];
4114 bufR = buffer[1];
4115
4116 cch[0] = &F2610->CH[0];
4117 cch[1] = &F2610->CH[1];
4118 cch[2] = &F2610->CH[2];
4119 cch[3] = &F2610->CH[3];
4120 cch[4] = &F2610->CH[4];
4121 cch[5] = &F2610->CH[5];
4122
4123 /* refresh PG and EG */
4124 refresh_fc_eg_chan( OPN, cch[0] );
4125 refresh_fc_eg_chan( OPN, cch[1] );
4126 if( (OPN->ST.mode & 0xc0) )
4127 {
4128 /* 3SLOT MODE */
4129 if( cch[2]->SLOT[SLOT1].Incr==-1)
4130 {
4131 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
4132 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
4133 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
4134 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
4135 }
4136 }
4137 else
4138 refresh_fc_eg_chan( OPN, cch[2] );
4139 refresh_fc_eg_chan( OPN, cch[3] );
4140 refresh_fc_eg_chan( OPN, cch[4] );
4141 refresh_fc_eg_chan( OPN, cch[5] );
4142
4143 /* buffering */
4144 for(i=0; i < length ; i++)
4145 {
4146
4147 advance_lfo(OPN);
4148
4149 /* clear output acc. */
4150 OPN->out_adpcm[OUTD_LEFT] = OPN->out_adpcm[OUTD_RIGHT] = OPN->out_adpcm[OUTD_CENTER] = 0;
4151 OPN->out_delta[OUTD_LEFT] = OPN->out_delta[OUTD_RIGHT] = OPN->out_delta[OUTD_CENTER] = 0;
4152 /* clear outputs */
4153 out_fm[0] = 0;
4154 out_fm[1] = 0;
4155 out_fm[2] = 0;
4156 out_fm[3] = 0;
4157 out_fm[4] = 0;
4158 out_fm[5] = 0;
4159
4160 /* advance envelope generator */
4161 OPN->eg_timer += OPN->eg_timer_add;
4162 while (OPN->eg_timer >= OPN->eg_timer_overflow)
4163 {
4164 OPN->eg_timer -= OPN->eg_timer_overflow;
4165 OPN->eg_cnt++;
4166
4167 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
4168 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
4169 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
4170 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
4171 advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]);
4172 advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]);
4173 }
4174
4175 /* calculate FM */
4176 chan_calc(OPN, cch[0], 0 );
4177 chan_calc(OPN, cch[1], 1 );
4178 chan_calc(OPN, cch[2], 2 );
4179 chan_calc(OPN, cch[3], 3 );
4180 chan_calc(OPN, cch[4], 4 );
4181 chan_calc(OPN, cch[5], 5 );
4182
4183 /* deltaT ADPCM */
4184 if( DELTAT->portstate&0x80 && ! F2610->MuteDeltaT )
4185 YM_DELTAT_ADPCM_CALC(DELTAT);
4186
4187 /* ADPCMA */
4188 for( j = 0; j < 6; j++ )
4189 {
4190 if( F2610->adpcm[j].flag )
4191 ADPCMA_calc_chan( F2610, &F2610->adpcm[j]);
4192 }
4193
4194 /* buffering */
4195 {
4196 int lt,rt;
4197
4198 /*lt = OPN->out_adpcm[OUTD_LEFT] + OPN->out_adpcm[OUTD_CENTER];
4199 rt = OPN->out_adpcm[OUTD_RIGHT] + OPN->out_adpcm[OUTD_CENTER];
4200 lt += (OPN->out_delta[OUTD_LEFT] + OPN->out_delta[OUTD_CENTER])>>9;
4201 rt += (OPN->out_delta[OUTD_RIGHT] + OPN->out_delta[OUTD_CENTER])>>9;
4202
4203 lt += ((out_fm[0]>>1) & OPN->pan[0]); // the shift right is verified on YM2610
4204 rt += ((out_fm[0]>>1) & OPN->pan[1]);
4205 lt += ((out_fm[1]>>1) & OPN->pan[2]);
4206 rt += ((out_fm[1]>>1) & OPN->pan[3]);
4207 lt += ((out_fm[2]>>1) & OPN->pan[4]);
4208 rt += ((out_fm[2]>>1) & OPN->pan[5]);
4209 lt += ((out_fm[3]>>1) & OPN->pan[6]);
4210 rt += ((out_fm[3]>>1) & OPN->pan[7]);
4211 lt += ((out_fm[4]>>1) & OPN->pan[8]);
4212 rt += ((out_fm[4]>>1) & OPN->pan[9]);
4213 lt += ((out_fm[5]>>1) & OPN->pan[10]);
4214 rt += ((out_fm[5]>>1) & OPN->pan[11]);*/
4215 lt = (OPN->out_adpcm[OUTD_LEFT] + OPN->out_adpcm[OUTD_CENTER]) << 1;
4216 rt = (OPN->out_adpcm[OUTD_RIGHT] + OPN->out_adpcm[OUTD_CENTER]) << 1;
4217 lt += (OPN->out_delta[OUTD_LEFT] + OPN->out_delta[OUTD_CENTER])>>8;
4218 rt += (OPN->out_delta[OUTD_RIGHT] + OPN->out_delta[OUTD_CENTER])>>8;
4219
4220 lt += (out_fm[0] & OPN->pan[0]);
4221 rt += (out_fm[0] & OPN->pan[1]);
4222 lt += (out_fm[1] & OPN->pan[2]);
4223 rt += (out_fm[1] & OPN->pan[3]);
4224 lt += (out_fm[2] & OPN->pan[4]);
4225 rt += (out_fm[2] & OPN->pan[5]);
4226 lt += (out_fm[3] & OPN->pan[6]);
4227 rt += (out_fm[3] & OPN->pan[7]);
4228 lt += (out_fm[4] & OPN->pan[8]);
4229 rt += (out_fm[4] & OPN->pan[9]);
4230 lt += (out_fm[5] & OPN->pan[10]);
4231 rt += (out_fm[5] & OPN->pan[11]);
4232
4233
4234 lt >>= FINAL_SH;
4235 rt >>= FINAL_SH;
4236
4237 //Limit( lt, MAXOUT, MINOUT );
4238 //Limit( rt, MAXOUT, MINOUT );
4239
4240 #ifdef SAVE_SAMPLE
4241 SAVE_ALL_CHANNELS
4242 #endif
4243
4244 /* buffering */
4245 bufL[i] = lt;
4246 bufR[i] = rt;
4247 }
4248
4249 /* timer A control */
4250 INTERNAL_TIMER_A( &OPN->ST , cch[2] )
4251 }
4252 INTERNAL_TIMER_B(&OPN->ST,length)
4253
4254 }
4255 #endif /* BUILD_YM2610B */
4256
4257
4258 #ifdef __STATE_H__
ym2610_postload(void * chip)4259 void ym2610_postload(void *chip)
4260 {
4261 if (chip)
4262 {
4263 YM2610 *F2610 = (YM2610 *)chip;
4264 int r;
4265
4266 /* SSG registers */
4267 for(r=0;r<16;r++)
4268 {
4269 (*F2610->OPN.ST.SSG->write)(F2610->OPN.ST.param,0,r);
4270 (*F2610->OPN.ST.SSG->write)(F2610->OPN.ST.param,1,F2610->REGS[r]);
4271 }
4272
4273 /* OPN registers */
4274 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
4275 for(r=0x30;r<0x9e;r++)
4276 if((r&3) != 3)
4277 {
4278 OPNWriteReg(&F2610->OPN,r,F2610->REGS[r]);
4279 OPNWriteReg(&F2610->OPN,r|0x100,F2610->REGS[r|0x100]);
4280 }
4281 /* FB / CONNECT , L / R / AMS / PMS */
4282 for(r=0xb0;r<0xb6;r++)
4283 if((r&3) != 3)
4284 {
4285 OPNWriteReg(&F2610->OPN,r,F2610->REGS[r]);
4286 OPNWriteReg(&F2610->OPN,r|0x100,F2610->REGS[r|0x100]);
4287 }
4288 /* FM channels */
4289 /*FM_channel_postload(F2610->CH,6);*/
4290
4291 /* rhythm(ADPCMA) */
4292 FM_ADPCMAWrite(F2610,1,F2610->REGS[0x101]);
4293 for( r=0 ; r<6 ; r++)
4294 {
4295 FM_ADPCMAWrite(F2610,r+0x08,F2610->REGS[r+0x108]);
4296 FM_ADPCMAWrite(F2610,r+0x10,F2610->REGS[r+0x110]);
4297 FM_ADPCMAWrite(F2610,r+0x18,F2610->REGS[r+0x118]);
4298 FM_ADPCMAWrite(F2610,r+0x20,F2610->REGS[r+0x120]);
4299 FM_ADPCMAWrite(F2610,r+0x28,F2610->REGS[r+0x128]);
4300 }
4301 /* Delta-T ADPCM unit */
4302 YM_DELTAT_postload(&F2610->deltaT , &F2610->REGS[0x010] );
4303 }
4304 }
4305
YM2610_save_state(YM2610 * F2610,const device_config * device)4306 static void YM2610_save_state(YM2610 *F2610, const device_config *device)
4307 {
4308 state_save_register_device_item_array(device, 0, F2610->REGS);
4309 FMsave_state_st(device,&F2610->OPN.ST);
4310 FMsave_state_channel(device,F2610->CH,6);
4311 /* 3slots */
4312 state_save_register_device_item_array(device, 0, F2610->OPN.SL3.fc);
4313 state_save_register_device_item(device, 0, F2610->OPN.SL3.fn_h);
4314 state_save_register_device_item_array(device, 0, F2610->OPN.SL3.kcode);
4315 /* address register1 */
4316 state_save_register_device_item(device, 0, F2610->addr_A1);
4317
4318 state_save_register_device_item(device, 0, F2610->adpcm_arrivedEndAddress);
4319 /* rythm(ADPCMA) */
4320 FMsave_state_adpcma(device,F2610->adpcm);
4321 /* Delta-T ADPCM unit */
4322 YM_DELTAT_savestate(device,&F2610->deltaT);
4323 }
4324 #endif /* _STATE_H */
4325
YM2610_deltat_status_set(void * chip,UINT8 changebits)4326 static void YM2610_deltat_status_set(void *chip, UINT8 changebits)
4327 {
4328 YM2610 *F2610 = (YM2610 *)chip;
4329 F2610->adpcm_arrivedEndAddress |= changebits;
4330 }
YM2610_deltat_status_reset(void * chip,UINT8 changebits)4331 static void YM2610_deltat_status_reset(void *chip, UINT8 changebits)
4332 {
4333 YM2610 *F2610 = (YM2610 *)chip;
4334 F2610->adpcm_arrivedEndAddress &= (~changebits);
4335 }
4336
4337 //void *ym2610_init(void *param, const device_config *device, int clock, int rate,
4338 // void *pcmroma,int pcmsizea,void *pcmromb,int pcmsizeb,
4339 // FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg)
ym2610_init(void * param,int clock,int rate,FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler,const ssg_callbacks * ssg)4340 void *ym2610_init(void *param, int clock, int rate,
4341 FM_TIMERHANDLER timer_handler,FM_IRQHANDLER IRQHandler, const ssg_callbacks *ssg)
4342 {
4343 YM2610 *F2610;
4344
4345 /* allocate extend state space */
4346 if( (F2610 = (YM2610 *)malloc(sizeof(YM2610)))==NULL)
4347 return NULL;
4348 /* clear */
4349 memset(F2610,0,sizeof(YM2610));
4350 /* allocate total level table (128kb space) */
4351 if( !init_tables() )
4352 {
4353 free( F2610 );
4354 return NULL;
4355 }
4356
4357 /* FM */
4358 F2610->OPN.ST.param = param;
4359 F2610->OPN.type = TYPE_YM2610;
4360 F2610->OPN.P_CH = F2610->CH;
4361 //F2610->OPN.ST.device = device;
4362 F2610->OPN.ST.clock = clock;
4363 F2610->OPN.ST.rate = rate;
4364 /* Extend handler */
4365 F2610->OPN.ST.timer_handler = timer_handler;
4366 F2610->OPN.ST.IRQ_Handler = IRQHandler;
4367 F2610->OPN.ST.SSG = ssg;
4368 /* ADPCM */
4369 //F2610->pcmbuf = (const UINT8 *)pcmroma;
4370 //F2610->pcm_size = pcmsizea;
4371 F2610->pcmbuf = NULL;
4372 F2610->pcm_size = 0x00;
4373 /* DELTA-T */
4374 //F2610->deltaT.memory = (UINT8 *)pcmromb;
4375 //F2610->deltaT.memory_size = pcmsizeb;
4376 F2610->deltaT.memory = NULL;
4377 F2610->deltaT.memory_size = 0x00;
4378 F2610->deltaT.memory_mask = 0x00;
4379
4380 F2610->deltaT.status_set_handler = YM2610_deltat_status_set;
4381 F2610->deltaT.status_reset_handler = YM2610_deltat_status_reset;
4382 F2610->deltaT.status_change_which_chip = F2610;
4383 F2610->deltaT.status_change_EOS_bit = 0x80; /* status flag: set bit7 on End Of Sample */
4384
4385 Init_ADPCMATable();
4386 #ifdef __STATE_H__
4387 YM2610_save_state(F2610, device);
4388 #endif
4389 return F2610;
4390 }
4391
4392 /* shut down emulator */
ym2610_shutdown(void * chip)4393 void ym2610_shutdown(void *chip)
4394 {
4395 YM2610 *F2610 = (YM2610 *)chip;
4396
4397 free(F2610->pcmbuf); F2610->pcmbuf = NULL;
4398 free(F2610->deltaT.memory); F2610->deltaT.memory = NULL;
4399
4400 FMCloseTable();
4401 free(F2610);
4402 }
4403
4404 /* reset one of chip */
ym2610_reset_chip(void * chip)4405 void ym2610_reset_chip(void *chip)
4406 {
4407 int i;
4408 YM2610 *F2610 = (YM2610 *)chip;
4409 FM_OPN *OPN = &F2610->OPN;
4410 YM_DELTAT *DELTAT = &F2610->deltaT;
4411
4412 /*astring name;
4413 device_t* dev = F2610->OPN.ST.device;*/
4414
4415 /* setup PCM buffers again */
4416 /*name.printf("%s",dev->tag());
4417 F2610->pcmbuf = (const UINT8 *)dev->machine->region(name)->base();
4418 F2610->pcm_size = dev->machine->region(name)->bytes();
4419 name.printf("%s.deltat",dev->tag());
4420 F2610->deltaT.memory = (UINT8 *)dev->machine->region(name)->base();
4421 if(F2610->deltaT.memory == NULL)
4422 {
4423 F2610->deltaT.memory = (UINT8*)F2610->pcmbuf;
4424 F2610->deltaT.memory_size = F2610->pcm_size;
4425 }
4426 else
4427 F2610->deltaT.memory_size = dev->machine->region(name)->bytes();*/
4428 F2610->pcmbuf = NULL;
4429 F2610->pcm_size = 0x00;
4430 F2610->deltaT.memory = NULL;
4431 F2610->deltaT.memory_size = 0x00;
4432 F2610->deltaT.memory_mask = 0x00;
4433
4434 /* Reset Prescaler */
4435 OPNSetPres( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
4436 /* reset SSG section */
4437 (*OPN->ST.SSG->reset)(OPN->ST.param);
4438 /* status clear */
4439 FM_IRQMASK_SET(&OPN->ST,0x03);
4440 FM_BUSY_CLEAR(&OPN->ST);
4441 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
4442
4443 OPN->eg_timer = 0;
4444 OPN->eg_cnt = 0;
4445
4446 FM_STATUS_RESET(&OPN->ST, 0xff);
4447
4448 reset_channels( &OPN->ST , F2610->CH , 6 );
4449 /* reset OPerator paramater */
4450 for(i = 0xb6 ; i >= 0xb4 ; i-- )
4451 {
4452 OPNWriteReg(OPN,i ,0xc0);
4453 OPNWriteReg(OPN,i|0x100,0xc0);
4454 }
4455 for(i = 0xb2 ; i >= 0x30 ; i-- )
4456 {
4457 OPNWriteReg(OPN,i ,0);
4458 OPNWriteReg(OPN,i|0x100,0);
4459 }
4460 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
4461 /**** ADPCM work initial ****/
4462 for( i = 0; i < 6 ; i++ )
4463 {
4464 F2610->adpcm[i].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/3.0);
4465 F2610->adpcm[i].now_addr = 0;
4466 F2610->adpcm[i].now_step = 0;
4467 F2610->adpcm[i].start = 0;
4468 F2610->adpcm[i].end = 0;
4469 /* F2610->adpcm[i].delta = 21866; */
4470 F2610->adpcm[i].vol_mul = 0;
4471 F2610->adpcm[i].pan = &OPN->out_adpcm[OUTD_CENTER]; /* default center */
4472 F2610->adpcm[i].flagMask = 1<<i;
4473 F2610->adpcm[i].flag = 0;
4474 F2610->adpcm[i].adpcm_acc = 0;
4475 F2610->adpcm[i].adpcm_step= 0;
4476 F2610->adpcm[i].adpcm_out = 0;
4477 }
4478 F2610->adpcmTL = 0x3f;
4479
4480 F2610->adpcm_arrivedEndAddress = 0;
4481
4482 /* DELTA-T unit */
4483 DELTAT->freqbase = OPN->ST.freqbase;
4484 DELTAT->output_pointer = OPN->out_delta;
4485 DELTAT->portshift = 8; /* allways 8bits shift */
4486 DELTAT->output_range = 1<<23;
4487 YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER,YM_DELTAT_EMULATION_MODE_YM2610);
4488 }
4489
4490 /* YM2610 write */
4491 /* n = number */
4492 /* a = address */
4493 /* v = value */
ym2610_write(void * chip,int a,UINT8 v)4494 int ym2610_write(void *chip, int a, UINT8 v)
4495 {
4496 YM2610 *F2610 = (YM2610 *)chip;
4497 FM_OPN *OPN = &F2610->OPN;
4498 int addr;
4499 int ch;
4500
4501 v &= 0xff; /* adjust to 8 bit bus */
4502
4503 switch( a&3 )
4504 {
4505 case 0: /* address port 0 */
4506 OPN->ST.address = v;
4507 F2610->addr_A1 = 0;
4508
4509 /* Write register to SSG emulator */
4510 if( v < 16 ) (*OPN->ST.SSG->write)(OPN->ST.param,0,v);
4511 break;
4512
4513 case 1: /* data port 0 */
4514 if (F2610->addr_A1 != 0)
4515 break; /* verified on real YM2608 */
4516
4517 addr = OPN->ST.address;
4518 F2610->REGS[addr] = v;
4519 switch(addr & 0xf0)
4520 {
4521 case 0x00: /* SSG section */
4522 /* Write data to SSG emulator */
4523 (*OPN->ST.SSG->write)(OPN->ST.param,a,v);
4524 break;
4525 case 0x10: /* DeltaT ADPCM */
4526 ym2610_update_req(OPN->ST.param);
4527
4528 switch(addr)
4529 {
4530 case 0x10: /* control 1 */
4531 case 0x11: /* control 2 */
4532 case 0x12: /* start address L */
4533 case 0x13: /* start address H */
4534 case 0x14: /* stop address L */
4535 case 0x15: /* stop address H */
4536
4537 case 0x19: /* delta-n L */
4538 case 0x1a: /* delta-n H */
4539 case 0x1b: /* volume */
4540 {
4541 YM_DELTAT_ADPCM_Write(&F2610->deltaT,addr-0x10,v);
4542 }
4543 break;
4544
4545 case 0x1c: /* FLAG CONTROL : Extend Status Clear/Mask */
4546 {
4547 UINT8 statusmask = ~v;
4548 /* set arrived flag mask */
4549 for(ch=0;ch<6;ch++)
4550 F2610->adpcm[ch].flagMask = statusmask&(1<<ch);
4551
4552 F2610->deltaT.status_change_EOS_bit = statusmask & 0x80; /* status flag: set bit7 on End Of Sample */
4553
4554 /* clear arrived flag */
4555 F2610->adpcm_arrivedEndAddress &= statusmask;
4556 }
4557 break;
4558
4559 default:
4560 #ifdef _DEBUG
4561 logerror("YM2610: write to unknown deltat register %02x val=%02x\n",addr,v);
4562 #endif
4563 break;
4564 }
4565
4566 break;
4567 case 0x20: /* Mode Register */
4568 ym2610_update_req(OPN->ST.param);
4569 OPNWriteMode(OPN,addr,v);
4570 break;
4571 default: /* OPN section */
4572 ym2610_update_req(OPN->ST.param);
4573 /* write register */
4574 OPNWriteReg(OPN,addr,v);
4575 }
4576 break;
4577
4578 case 2: /* address port 1 */
4579 OPN->ST.address = v;
4580 F2610->addr_A1 = 1;
4581 break;
4582
4583 case 3: /* data port 1 */
4584 if (F2610->addr_A1 != 1)
4585 break; /* verified on real YM2608 */
4586
4587 ym2610_update_req(OPN->ST.param);
4588 addr = OPN->ST.address;
4589 F2610->REGS[addr | 0x100] = v;
4590 if( addr < 0x30 )
4591 /* 100-12f : ADPCM A section */
4592 FM_ADPCMAWrite(F2610,addr,v);
4593 else
4594 OPNWriteReg(OPN,addr | 0x100,v);
4595 }
4596 return OPN->ST.irq;
4597 }
4598
ym2610_read(void * chip,int a)4599 UINT8 ym2610_read(void *chip,int a)
4600 {
4601 YM2610 *F2610 = (YM2610 *)chip;
4602 int addr = F2610->OPN.ST.address;
4603 UINT8 ret = 0;
4604
4605 switch( a&3)
4606 {
4607 case 0: /* status 0 : YM2203 compatible */
4608 ret = FM_STATUS_FLAG(&F2610->OPN.ST) & 0x83;
4609 break;
4610 case 1: /* data 0 */
4611 if( addr < 16 ) ret = (*F2610->OPN.ST.SSG->read)(F2610->OPN.ST.param);
4612 if( addr == 0xff ) ret = 0x01;
4613 break;
4614 case 2: /* status 1 : ADPCM status */
4615 /* ADPCM STATUS (arrived End Address) */
4616 /* B,--,A5,A4,A3,A2,A1,A0 */
4617 /* B = ADPCM-B(DELTA-T) arrived end address */
4618 /* A0-A5 = ADPCM-A arrived end address */
4619 ret = F2610->adpcm_arrivedEndAddress;
4620 break;
4621 case 3:
4622 ret = 0;
4623 break;
4624 }
4625 return ret;
4626 }
4627
ym2610_timer_over(void * chip,int c)4628 int ym2610_timer_over(void *chip,int c)
4629 {
4630 YM2610 *F2610 = (YM2610 *)chip;
4631
4632 if( c )
4633 { /* Timer B */
4634 TimerBOver( &(F2610->OPN.ST) );
4635 }
4636 else
4637 { /* Timer A */
4638 ym2610_update_req(F2610->OPN.ST.param);
4639 /* timer update */
4640 TimerAOver( &(F2610->OPN.ST) );
4641 /* CSM mode key,TL controll */
4642 if( F2610->OPN.ST.mode & 0x80 )
4643 { /* CSM mode total level latch and auto key on */
4644 CSMKeyControll( F2610->OPN.type, &(F2610->CH[2]) );
4645 }
4646 }
4647 return F2610->OPN.ST.irq;
4648 }
4649
ym2610_write_pcmrom(void * chip,UINT8 rom_id,offs_t ROMSize,offs_t DataStart,offs_t DataLength,const UINT8 * ROMData)4650 void ym2610_write_pcmrom(void *chip, UINT8 rom_id, offs_t ROMSize, offs_t DataStart,
4651 offs_t DataLength, const UINT8* ROMData)
4652 {
4653 YM2610 *F2610 = (YM2610 *)chip;
4654
4655 switch(rom_id)
4656 {
4657 case 0x01: // ADPCM
4658 if (F2610->pcm_size != ROMSize)
4659 {
4660 F2610->pcmbuf = (UINT8*)realloc(F2610->pcmbuf, ROMSize);
4661 F2610->pcm_size = ROMSize;
4662 memset(F2610->pcmbuf, 0xFF, ROMSize);
4663 }
4664 if (DataStart > ROMSize)
4665 return;
4666 if (DataStart + DataLength > ROMSize)
4667 DataLength = ROMSize - DataStart;
4668
4669 memcpy(F2610->pcmbuf + DataStart, ROMData, DataLength);
4670 break;
4671 case 0x02: // DELTA-T
4672 if (F2610->deltaT.memory_size != ROMSize)
4673 {
4674 F2610->deltaT.memory = (UINT8*)realloc(F2610->deltaT.memory, ROMSize);
4675 F2610->deltaT.memory_size = ROMSize;
4676 memset(F2610->deltaT.memory, 0xFF, ROMSize);
4677 YM_DELTAT_calc_mem_mask(&F2610->deltaT);
4678 }
4679 if (DataStart > ROMSize)
4680 return;
4681 if (DataStart + DataLength > ROMSize)
4682 DataLength = ROMSize - DataStart;
4683
4684 memcpy(F2610->deltaT.memory + DataStart, ROMData, DataLength);
4685 break;
4686 }
4687
4688 return;
4689 }
4690
ym2610_set_mutemask(void * chip,UINT32 MuteMask)4691 void ym2610_set_mutemask(void *chip, UINT32 MuteMask)
4692 {
4693 YM2610 *F2610 = (YM2610 *)chip;
4694 UINT8 CurChn;
4695
4696 for (CurChn = 0; CurChn < 6; CurChn ++)
4697 F2610->CH[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
4698 for (CurChn = 0; CurChn < 6; CurChn ++)
4699 F2610->adpcm[CurChn].Muted = (MuteMask >> (CurChn + 6)) & 0x01;
4700 F2610->MuteDeltaT = (MuteMask >> 12) & 0x01;
4701
4702 return;
4703 }
4704 #endif /* (BUILD_YM2610||BUILD_YM2610B) */
4705