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