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