Add VCS links
[debian-dgen.git] / fm.c
blobf46da71de9c00338cd48ff00b59eacaf01eb6637
1 #define YM2610B_WARNING
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)
15 ** History:
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)
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
27 ** 22-05-2003 Jarek Burczynski:
28 ** - fixed LFO PM calculations (copy&paste bugfix)
30 ** 08-05-2003 Jarek Burczynski:
31 ** - fixed SSG support
33 ** 22-04-2003 Jarek Burczynski:
34 ** - implemented 100% correct LFO generator (verified on real YM2610 and YM2608)
36 ** 15-04-2003 Jarek Burczynski:
37 ** - added support for YM2608's register 0x110 - status mask
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.
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)
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)
54 ** 18-12-2001 Jarek Burczynski:
55 ** - added SSG-EG support (verified on real YM2203)
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).
69 ** 23-07-2001 Jarek Burczynski, Nicola Salmoria:
70 ** - corrected YM2610 ADPCM type A algorithm and tables (verified on real chip)
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).
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).
84 ** 09-12-98 hiro-shi:
85 ** change ADPCM volume. (8->16, 48->64)
86 ** replace ym2610 ch0/3 (YM-2610B)
87 ** init cur_chip (restart bug fix)
88 ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
89 ** add ADPCM_SHIFT_MASK
90 ** change ADPCMA_DECODE_MIN/MAX.
96 /************************************************************************/
97 /* comment of hiro-shi(Hiromitsu Shioya) */
98 /* YM2610(B) = OPN-B */
99 /* YM2610 : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
100 /* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
101 /************************************************************************/
103 #include <stdio.h>
104 #include <stdlib.h>
105 #include <string.h>
106 #include <stdarg.h>
107 #include <math.h>
108 #include "fm.h"
111 #ifndef PI
112 #define PI 3.14159265358979323846
113 #endif
116 /* include external DELTA-T unit (when needed) */
117 #if (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
118 #include "ymdeltat.h"
119 #endif
121 /* shared function building option */
122 #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B||BUILD_YM2612)
123 #define BUILD_OPN_PRESCALER (BUILD_YM2203||BUILD_YM2608)
126 /* globals */
127 #define TYPE_SSG 0x01 /* SSG support */
128 #define TYPE_LFOPAN 0x02 /* OPN type LFO and PAN */
129 #define TYPE_6CH 0x04 /* FM 6CH / 3CH */
130 #define TYPE_DAC 0x08 /* YM2612's DAC device */
131 #define TYPE_ADPCM 0x10 /* two ADPCM units */
132 #define TYPE_2610 0x20 /* bogus flag to differentiate 2608 from 2610 */
134 #define TYPE_YM2203 (TYPE_SSG)
135 #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
136 #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM |TYPE_2610)
137 #define TYPE_YM2612 (TYPE_DAC |TYPE_LFOPAN |TYPE_6CH)
141 #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
142 #define EG_SH 16 /* 16.16 fixed point (envelope generator timing) */
143 #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
144 #define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
146 #define FREQ_MASK ((1<<FREQ_SH)-1)
148 #define ENV_BITS 10
149 #define ENV_LEN (1<<ENV_BITS)
150 #define ENV_STEP (128.0/ENV_LEN)
152 #define MAX_ATT_INDEX (ENV_LEN-1) /* 1023 */
153 #define MIN_ATT_INDEX (0) /* 0 */
155 #define EG_ATT 4
156 #define EG_DEC 3
157 #define EG_SUS 2
158 #define EG_REL 1
159 #define EG_OFF 0
161 #define SIN_BITS 10
162 #define SIN_LEN (1<<SIN_BITS)
163 #define SIN_MASK (SIN_LEN-1)
165 #define TL_RES_LEN (256) /* 8 bits addressing (real chip) */
168 #if (FM_SAMPLE_BITS==16)
169 #define FINAL_SH (0)
170 #define MAXOUT (+32767)
171 #define MINOUT (-32768)
172 #else
173 #define FINAL_SH (8)
174 #define MAXOUT (+127)
175 #define MINOUT (-128)
176 #endif
179 /* TL_TAB_LEN is calculated as:
180 * 13 - sinus amplitude bits (Y axis)
181 * 2 - sinus sign bit (Y axis)
182 * TL_RES_LEN - sinus resolution (X axis)
184 #define TL_TAB_LEN (13*2*TL_RES_LEN)
185 static signed int tl_tab[TL_TAB_LEN];
187 #define ENV_QUIET (TL_TAB_LEN>>3)
189 /* sin waveform table in 'decibel' scale */
190 static unsigned int sin_tab[SIN_LEN];
192 /* sustain level table (3dB per step) */
193 /* bit0, bit1, bit2, bit3, bit4, bit5, bit6 */
194 /* 1, 2, 4, 8, 16, 32, 64 (value)*/
195 /* 0.75, 1.5, 3, 6, 12, 24, 48 (dB)*/
197 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
198 #define SC(db) (UINT32) ( db * (4.0/ENV_STEP) )
199 static const UINT32 sl_table[16]={
200 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
201 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
203 #undef SC
206 #define RATE_STEPS (8)
207 static const UINT8 eg_inc[19*RATE_STEPS]={
209 /*cycle:0 1 2 3 4 5 6 7*/
211 /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..11 0 (increment by 0 or 1) */
212 /* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..11 1 */
213 /* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..11 2 */
214 /* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..11 3 */
216 /* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 12 0 (increment by 1) */
217 /* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 12 1 */
218 /* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 12 2 */
219 /* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 12 3 */
221 /* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 13 0 (increment by 2) */
222 /* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 13 1 */
223 /*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 13 2 */
224 /*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 13 3 */
226 /*12 */ 4,4, 4,4, 4,4, 4,4, /* rate 14 0 (increment by 4) */
227 /*13 */ 4,4, 4,8, 4,4, 4,8, /* rate 14 1 */
228 /*14 */ 4,8, 4,8, 4,8, 4,8, /* rate 14 2 */
229 /*15 */ 4,8, 8,8, 4,8, 8,8, /* rate 14 3 */
231 /*16 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 8) */
232 /*17 */ 16,16,16,16,16,16,16,16, /* rates 15 2, 15 3 for attack */
233 /*18 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
237 #define O(a) (a*RATE_STEPS)
239 /*note that there is no O(17) in this table - it's directly in the code */
240 static const UINT8 eg_rate_select[32+64+32]={ /* Envelope Generator rates (32 + 64 rates + 32 RKS) */
241 /* 32 infinite time rates */
242 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
243 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
244 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
245 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
247 /* rates 00-11 */
248 O( 0),O( 1),O( 2),O( 3),
249 O( 0),O( 1),O( 2),O( 3),
250 O( 0),O( 1),O( 2),O( 3),
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),
261 /* rate 12 */
262 O( 4),O( 5),O( 6),O( 7),
264 /* rate 13 */
265 O( 8),O( 9),O(10),O(11),
267 /* rate 14 */
268 O(12),O(13),O(14),O(15),
270 /* rate 15 */
271 O(16),O(16),O(16),O(16),
273 /* 32 dummy rates (same as 15 3) */
274 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
275 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
276 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
277 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
281 static const UINT8 eg_rate_select2612[32+64+32]={ /* Envelope Generator rates (32 + 64 rates + 32 RKS) */
282 /* 32 infinite time rates */
283 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
284 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
285 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
286 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
288 /* rates 00-11 */
289 O( 18),O( 18),O( 0),O( 0),
290 O( 0),O( 0),O( 2),O( 2), // Nemesis's tests
292 O( 0),O( 1),O( 2),O( 3),
293 O( 0),O( 1),O( 2),O( 3),
294 O( 0),O( 1),O( 2),O( 3),
295 O( 0),O( 1),O( 2),O( 3),
296 O( 0),O( 1),O( 2),O( 3),
297 O( 0),O( 1),O( 2),O( 3),
298 O( 0),O( 1),O( 2),O( 3),
299 O( 0),O( 1),O( 2),O( 3),
300 O( 0),O( 1),O( 2),O( 3),
301 O( 0),O( 1),O( 2),O( 3),
303 /* rate 12 */
304 O( 4),O( 5),O( 6),O( 7),
306 /* rate 13 */
307 O( 8),O( 9),O(10),O(11),
309 /* rate 14 */
310 O(12),O(13),O(14),O(15),
312 /* rate 15 */
313 O(16),O(16),O(16),O(16),
315 /* 32 dummy rates (same as 15 3) */
316 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
317 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
318 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16),
319 O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
322 #undef O
324 /*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15*/
325 /*shift 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0 */
326 /*mask 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0, 0 */
328 #define O(a) (a*1)
329 static const UINT8 eg_rate_shift[32+64+32]={ /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */
330 /* 32 infinite time rates */
331 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
332 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
333 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
334 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
336 /* rates 00-11 */
337 O(11),O(11),O(11),O(11),
338 O(10),O(10),O(10),O(10),
339 O( 9),O( 9),O( 9),O( 9),
340 O( 8),O( 8),O( 8),O( 8),
341 O( 7),O( 7),O( 7),O( 7),
342 O( 6),O( 6),O( 6),O( 6),
343 O( 5),O( 5),O( 5),O( 5),
344 O( 4),O( 4),O( 4),O( 4),
345 O( 3),O( 3),O( 3),O( 3),
346 O( 2),O( 2),O( 2),O( 2),
347 O( 1),O( 1),O( 1),O( 1),
348 O( 0),O( 0),O( 0),O( 0),
350 /* rate 12 */
351 O( 0),O( 0),O( 0),O( 0),
353 /* rate 13 */
354 O( 0),O( 0),O( 0),O( 0),
356 /* rate 14 */
357 O( 0),O( 0),O( 0),O( 0),
359 /* rate 15 */
360 O( 0),O( 0),O( 0),O( 0),
362 /* 32 dummy rates (same as 15 3) */
363 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
364 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
365 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
366 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0)
369 #undef O
371 static const UINT8 dt_tab[4 * 32]={
372 /* this is YM2151 and YM2612 phase increment data (in 10.10 fixed point format)*/
373 /* FD=0 */
374 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
375 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
376 /* FD=1 */
377 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
378 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
379 /* FD=2 */
380 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
381 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
382 /* FD=3 */
383 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
384 8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
388 /* OPN key frequency number -> key code follow table */
389 /* fnum higher 4bit -> keycode lower 2bit */
390 static const UINT8 opn_fktable[16] = {0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
393 /* 8 LFO speed parameters */
394 /* each value represents number of samples that one LFO level will last for */
395 static const UINT32 lfo_samples_per_step[8] = {108, 77, 71, 67, 62, 44, 8, 5};
399 /*There are 4 different LFO AM depths available, they are:
400 0 dB, 1.4 dB, 5.9 dB, 11.8 dB
401 Here is how it is generated (in EG steps):
403 11.8 dB = 0, 2, 4, 6, 8, 10,12,14,16...126,126,124,122,120,118,....4,2,0
404 5.9 dB = 0, 1, 2, 3, 4, 5, 6, 7, 8....63, 63, 62, 61, 60, 59,.....2,1,0
405 1.4 dB = 0, 0, 0, 0, 1, 1, 1, 1, 2,...15, 15, 15, 15, 14, 14,.....0,0,0
407 (1.4 dB is loosing precision as you can see)
409 It's implemented as generator from 0..126 with step 2 then a shift
410 right N times, where N is:
411 8 for 0 dB
412 3 for 1.4 dB
413 1 for 5.9 dB
414 0 for 11.8 dB
416 static const UINT8 lfo_ams_depth_shift[4] = {8, 3, 1, 0};
420 /*There are 8 different LFO PM depths available, they are:
421 0, 3.4, 6.7, 10, 14, 20, 40, 80 (cents)
423 Modulation level at each depth depends on F-NUMBER bits: 4,5,6,7,8,9,10
424 (bits 8,9,10 = FNUM MSB from OCT/FNUM register)
426 Here we store only first quarter (positive one) of full waveform.
427 Full table (lfo_pm_table) containing all 128 waveforms is build
428 at run (init) time.
430 One value in table below represents 4 (four) basic LFO steps
431 (1 PM step = 4 AM steps).
433 For example:
434 at LFO SPEED=0 (which is 108 samples per basic LFO step)
435 one value from "lfo_pm_output" table lasts for 432 consecutive
436 samples (4*108=432) and one full LFO waveform cycle lasts for 13824
437 samples (32*432=13824; 32 because we store only a quarter of whole
438 waveform in the table below)
440 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 */
441 /* FNUM BIT 4: 000 0001xxxx */
442 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
443 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
444 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
445 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
446 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0},
447 /* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0},
448 /* DEPTH 6 */ {0, 0, 0, 0, 0, 0, 0, 0},
449 /* DEPTH 7 */ {0, 0, 0, 0, 1, 1, 1, 1},
451 /* FNUM BIT 5: 000 0010xxxx */
452 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
453 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
454 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
455 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
456 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 0},
457 /* DEPTH 5 */ {0, 0, 0, 0, 0, 0, 0, 0},
458 /* DEPTH 6 */ {0, 0, 0, 0, 1, 1, 1, 1},
459 /* DEPTH 7 */ {0, 0, 1, 1, 2, 2, 2, 3},
461 /* FNUM BIT 6: 000 0100xxxx */
462 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
463 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
464 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 0, 0},
465 /* DEPTH 3 */ {0, 0, 0, 0, 0, 0, 0, 0},
466 /* DEPTH 4 */ {0, 0, 0, 0, 0, 0, 0, 1},
467 /* DEPTH 5 */ {0, 0, 0, 0, 1, 1, 1, 1},
468 /* DEPTH 6 */ {0, 0, 1, 1, 2, 2, 2, 3},
469 /* DEPTH 7 */ {0, 0, 2, 3, 4, 4, 5, 6},
471 /* FNUM BIT 7: 000 1000xxxx */
472 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
473 /* DEPTH 1 */ {0, 0, 0, 0, 0, 0, 0, 0},
474 /* DEPTH 2 */ {0, 0, 0, 0, 0, 0, 1, 1},
475 /* DEPTH 3 */ {0, 0, 0, 0, 1, 1, 1, 1},
476 /* DEPTH 4 */ {0, 0, 0, 1, 1, 1, 1, 2},
477 /* DEPTH 5 */ {0, 0, 1, 1, 2, 2, 2, 3},
478 /* DEPTH 6 */ {0, 0, 2, 3, 4, 4, 5, 6},
479 /* DEPTH 7 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
481 /* FNUM BIT 8: 001 0000xxxx */
482 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
483 /* DEPTH 1 */ {0, 0, 0, 0, 1, 1, 1, 1},
484 /* DEPTH 2 */ {0, 0, 0, 1, 1, 1, 2, 2},
485 /* DEPTH 3 */ {0, 0, 1, 1, 2, 2, 3, 3},
486 /* DEPTH 4 */ {0, 0, 1, 2, 2, 2, 3, 4},
487 /* DEPTH 5 */ {0, 0, 2, 3, 4, 4, 5, 6},
488 /* DEPTH 6 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
489 /* DEPTH 7 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
491 /* FNUM BIT 9: 010 0000xxxx */
492 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
493 /* DEPTH 1 */ {0, 0, 0, 0, 2, 2, 2, 2},
494 /* DEPTH 2 */ {0, 0, 0, 2, 2, 2, 4, 4},
495 /* DEPTH 3 */ {0, 0, 2, 2, 4, 4, 6, 6},
496 /* DEPTH 4 */ {0, 0, 2, 4, 4, 4, 6, 8},
497 /* DEPTH 5 */ {0, 0, 4, 6, 8, 8, 0xa, 0xc},
498 /* DEPTH 6 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
499 /* DEPTH 7 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30},
501 /* FNUM BIT10: 100 0000xxxx */
502 /* DEPTH 0 */ {0, 0, 0, 0, 0, 0, 0, 0},
503 /* DEPTH 1 */ {0, 0, 0, 0, 4, 4, 4, 4},
504 /* DEPTH 2 */ {0, 0, 0, 4, 4, 4, 8, 8},
505 /* DEPTH 3 */ {0, 0, 4, 4, 8, 8, 0xc, 0xc},
506 /* DEPTH 4 */ {0, 0, 4, 8, 8, 8, 0xc,0x10},
507 /* DEPTH 5 */ {0, 0, 8, 0xc,0x10,0x10,0x14,0x18},
508 /* DEPTH 6 */ {0, 0,0x10,0x18,0x20,0x20,0x28,0x30},
509 /* DEPTH 7 */ {0, 0,0x20,0x30,0x40,0x40,0x50,0x60},
513 /* all 128 LFO PM waveforms */
514 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 */
520 /* register number to channel number , slot offset */
521 #define OPN_CHAN(N) (N&3)
522 #define OPN_SLOT(N) ((N>>2)&3)
524 /* slot number */
525 #define SLOT1 0
526 #define SLOT2 2
527 #define SLOT3 1
528 #define SLOT4 3
530 /* bit0 = Right enable , bit1 = Left enable */
531 #define OUTD_RIGHT 1
532 #define OUTD_LEFT 2
533 #define OUTD_CENTER 3
536 /* save output as raw 16-bit sample */
537 /* #define SAVE_SAMPLE */
539 #ifdef SAVE_SAMPLE
540 static FILE *sample[1];
541 #if 1 /*save to MONO file */
542 #define SAVE_ALL_CHANNELS \
543 { signed int pom = lt; \
544 fputc((unsigned short)pom&0xff,sample[0]); \
545 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
547 #else /*save to STEREO file */
548 #define SAVE_ALL_CHANNELS \
549 { signed int pom = lt; \
550 fputc((unsigned short)pom&0xff,sample[0]); \
551 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
552 pom = rt; \
553 fputc((unsigned short)pom&0xff,sample[0]); \
554 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
556 #endif
557 #endif
560 /* struct describing a single operator (SLOT) */
561 typedef struct
563 INT32 *DT; /* detune :dt_tab[DT] */
564 UINT8 KSR; /* key scale rate :3-KSR */
565 UINT32 ar; /* attack rate */
566 UINT32 d1r; /* decay rate */
567 UINT32 d2r; /* sustain rate */
568 UINT32 rr; /* release rate */
569 UINT8 ksr; /* key scale rate :kcode>>(3-KSR) */
570 UINT32 mul; /* multiple :ML_TABLE[ML] */
572 /* Phase Generator */
573 UINT32 phase; /* phase counter */
574 INT32 Incr; /* phase step */
576 /* Envelope Generator */
577 UINT8 state; /* phase type */
578 UINT32 tl; /* total level: TL << 3 */
579 INT32 volume; /* envelope counter */
580 UINT32 sl; /* sustain level:sl_table[SL] */
581 UINT32 vol_out; /* current output from EG circuit (without AM from LFO) */
583 UINT8 eg_sh_ar; /* (attack state) */
584 UINT8 eg_sel_ar; /* (attack state) */
585 UINT8 eg_sh_d1r; /* (decay state) */
586 UINT8 eg_sel_d1r; /* (decay state) */
587 UINT8 eg_sh_d2r; /* (sustain state) */
588 UINT8 eg_sel_d2r; /* (sustain state) */
589 UINT8 eg_sh_rr; /* (release state) */
590 UINT8 eg_sel_rr; /* (release state) */
592 UINT8 ssg; /* SSG-EG waveform */
593 UINT8 ssgn; /* SSG-EG negated output */
595 UINT32 key; /* 0=last key was KEY OFF, 1=KEY ON */
597 /* LFO */
598 UINT32 AMmask; /* AM enable flag */
600 } FM_SLOT;
602 typedef struct
604 FM_SLOT SLOT[4]; /* four SLOTs (operators) */
606 UINT8 ALGO; /* algorithm */
607 UINT8 FB; /* feedback shift */
608 INT32 op1_out[2]; /* op1 output for feedback */
610 INT32 *connect1; /* SLOT1 output pointer */
611 INT32 *connect3; /* SLOT3 output pointer */
612 INT32 *connect2; /* SLOT2 output pointer */
613 INT32 *connect4; /* SLOT4 output pointer */
615 INT32 *mem_connect;/* where to put the delayed sample (MEM) */
616 INT32 mem_value; /* delayed sample (MEM) value */
618 INT32 pms; /* channel PMS */
619 UINT8 ams; /* channel AMS */
621 UINT32 fc; /* fnum,blk:adjusted to sample rate */
622 UINT8 kcode; /* key code: */
623 UINT32 block_fnum; /* current blk/fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
624 } FM_CH;
627 typedef struct
629 UINT8 index; /* this chip index (number of chip) */
630 int clock; /* master clock (Hz) */
631 int rate; /* sampling rate (Hz) */
632 double freqbase; /* frequency base */
633 double TimerBase; /* Timer base time */
634 #if FM_BUSY_FLAG_SUPPORT
635 double BusyExpire; /* ExpireTime of Busy clear */
636 #endif
637 UINT8 address; /* address register */
638 UINT8 irq; /* interrupt level */
639 UINT8 irqmask; /* irq mask */
640 UINT8 status; /* status flag */
641 UINT32 mode; /* mode CSM / 3SLOT */
642 UINT8 prescaler_sel;/* prescaler selector */
643 UINT8 fn_h; /* freq latch */
644 int TA; /* timer a */
645 int TAC; /* timer a counter */
646 UINT8 TB; /* timer b */
647 int TBC; /* timer b counter */
648 /* local time tables */
649 INT32 dt_tab[8][32];/* DeTune table */
650 /* Extention Timer and IRQ handler */
651 FM_TIMERHANDLER Timer_Handler;
652 FM_IRQHANDLER IRQ_Handler;
653 } FM_ST;
657 /***********************************************************/
658 /* OPN unit */
659 /***********************************************************/
661 /* OPN 3slot struct */
662 typedef struct
664 UINT32 fc[3]; /* fnum3,blk3: calculated */
665 UINT8 fn_h; /* freq3 latch */
666 UINT8 kcode[3]; /* key code */
667 UINT32 block_fnum[3]; /* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
668 } FM_3SLOT;
670 /* OPN/A/B common state */
671 typedef struct
673 UINT8 type; /* chip type */
674 FM_ST ST; /* general state */
675 FM_3SLOT SL3; /* 3 slot mode state */
676 FM_CH *P_CH; /* pointer of CH */
677 unsigned int pan[6*2]; /* fm channels output masks (0xffffffff = enable) */
679 UINT32 eg_cnt; /* global envelope generator counter */
680 UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/64/3 */
681 UINT32 eg_timer_add; /* step of eg_timer */
682 UINT32 eg_timer_overflow;/* envelope generator timer overlfows every 3 samples (on real chip) */
685 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
686 but LFO works with one more bit of a precision so we really need 4096 elements */
688 UINT32 fn_table[4096]; /* fnumber->increment counter */
689 UINT32 fn_max;
691 /* LFO */
692 UINT32 lfo_cnt;
693 UINT32 lfo_inc;
695 UINT32 lfo_freq[8]; /* LFO FREQ table */
696 } FM_OPN;
700 /* current chip state */
701 static void *cur_chip = 0; /* pointer of current chip struct */
702 static FM_ST *State; /* basic status */
703 static FM_CH *cch[8]; /* pointer of FM channels */
706 static INT32 m2,c1,c2; /* Phase Modulation input for operators 2,3,4 */
707 static INT32 mem; /* one sample delay memory */
709 static INT32 out_fm[8]; /* outputs of working channels */
711 #if (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
712 static INT32 out_adpcm[4]; /* channel output NONE,LEFT,RIGHT or CENTER for YM2608/YM2610 ADPCM */
713 static INT32 out_delta[4]; /* channel output NONE,LEFT,RIGHT or CENTER for YM2608/YM2610 DELTAT*/
714 #endif
716 static UINT32 LFO_AM; /* runtime LFO calculations helper */
717 static INT32 LFO_PM; /* runtime LFO calculations helper */
719 /* log output level */
720 #define LOG_ERR 3 /* ERROR */
721 #define LOG_WAR 2 /* WARNING */
722 #define LOG_INF 1 /* INFORMATION */
723 #define LOG_LEVEL LOG_INF
725 #define LOG(n,x) (void)0
727 /* limitter */
728 #define Limit(val, max,min) { \
729 if ( val > max ) val = max; \
730 else if ( val < min ) val = min; \
734 /* status set and IRQ handling */
735 INLINE void FM_STATUS_SET(FM_ST *ST,int flag)
737 /* set status flag */
738 ST->status |= flag;
739 if ( !(ST->irq) && (ST->status & ST->irqmask) )
741 ST->irq = 1;
742 /* callback user interrupt handler (IRQ is OFF to ON) */
743 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,1);
747 /* status reset and IRQ handling */
748 INLINE void FM_STATUS_RESET(FM_ST *ST,int flag)
750 /* reset status flag */
751 ST->status &=~flag;
752 if ( (ST->irq) && !(ST->status & ST->irqmask) )
754 ST->irq = 0;
755 /* callback user interrupt handler (IRQ is ON to OFF) */
756 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,0);
760 /* IRQ mask set */
761 INLINE void FM_IRQMASK_SET(FM_ST *ST,int flag)
763 ST->irqmask = flag;
764 /* IRQ handling check */
765 FM_STATUS_SET(ST,0);
766 FM_STATUS_RESET(ST,0);
769 /* OPN Mode Register Write */
770 INLINE void set_timers( FM_ST *ST, int n, int v )
772 /* b7 = CSM MODE */
773 /* b6 = 3 slot mode */
774 /* b5 = reset b */
775 /* b4 = reset a */
776 /* b3 = timer enable b */
777 /* b2 = timer enable a */
778 /* b1 = load b */
779 /* b0 = load a */
780 ST->mode = v;
782 /* reset Timer b flag */
783 if( v & 0x20 )
784 FM_STATUS_RESET(ST,0x02);
785 /* reset Timer a flag */
786 if( v & 0x10 )
787 FM_STATUS_RESET(ST,0x01);
788 /* load b */
789 if( v & 0x02 )
791 if( ST->TBC == 0 )
793 ST->TBC = ( 256-ST->TB)<<4;
794 /* External timer handler */
795 if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,ST->TBC,ST->TimerBase);
798 else
799 { /* stop timer b */
800 if( ST->TBC != 0 )
802 ST->TBC = 0;
803 if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,0,ST->TimerBase);
806 /* load a */
807 if( v & 0x01 )
809 if( ST->TAC == 0 )
811 ST->TAC = (1024-ST->TA);
812 /* External timer handler */
813 if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,ST->TAC,ST->TimerBase);
816 else
817 { /* stop timer a */
818 if( ST->TAC != 0 )
820 ST->TAC = 0;
821 if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,0,ST->TimerBase);
827 /* Timer A Overflow */
828 INLINE void TimerAOver(FM_ST *ST)
830 /* set status (if enabled) */
831 if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
832 /* clear or reload the counter */
833 ST->TAC = (1024-ST->TA);
834 if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,0,ST->TAC,ST->TimerBase);
836 /* Timer B Overflow */
837 INLINE void TimerBOver(FM_ST *ST)
839 /* set status (if enabled) */
840 if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
841 /* clear or reload the counter */
842 ST->TBC = ( 256-ST->TB)<<4;
843 if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,1,ST->TBC,ST->TimerBase);
847 #if FM_INTERNAL_TIMER
848 /* ----- internal timer mode , update timer */
850 /* ---------- calculate timer A ---------- */
851 #define INTERNAL_TIMER_A(type, ST, CSM_CH) \
853 if( ST->TAC && (ST->Timer_Handler==0) ) \
854 if( (ST->TAC -= (int)(ST->freqbase*4096)) <= 0 ) \
856 TimerAOver( ST ); \
857 /* CSM mode total level latch and auto key on */ \
858 if( ST->mode & 0x80 ) \
859 CSMKeyControll(type, CSM_CH ); \
862 /* ---------- calculate timer B ---------- */
863 #define INTERNAL_TIMER_B(ST,step) \
865 if( ST->TBC && (ST->Timer_Handler==0) ) \
866 if( (ST->TBC -= (int)(ST->freqbase*4096*step)) <= 0 ) \
867 TimerBOver( ST ); \
869 #else /* FM_INTERNAL_TIMER */
870 /* external timer mode */
871 #define INTERNAL_TIMER_A(type, ST, CSM_CH)
872 #define INTERNAL_TIMER_B(ST,step)
873 #endif /* FM_INTERNAL_TIMER */
877 #if FM_BUSY_FLAG_SUPPORT
878 INLINE UINT8 FM_STATUS_FLAG(FM_ST *ST)
880 if( ST->BusyExpire )
882 if( (ST->BusyExpire - FM_GET_TIME_NOW()) > 0)
883 return ST->status | 0x80; /* with busy */
884 /* expire */
885 ST->BusyExpire = 0;
887 return ST->status;
889 INLINE void FM_BUSY_SET(FM_ST *ST,int busyclock )
891 ST->BusyExpire = FM_GET_TIME_NOW() + (ST->TimerBase * busyclock);
893 #define FM_BUSY_CLEAR(ST) ((ST)->BusyExpire = 0)
894 #else
895 #define FM_STATUS_FLAG(ST) ((ST)->status)
896 #define FM_BUSY_SET(ST,bclock) {}
897 #define FM_BUSY_CLEAR(ST) {}
898 #endif
903 INLINE void FM_KEYON(UINT8 type, FM_CH *CH , int s )
905 FM_SLOT *SLOT = &CH->SLOT[s];
906 if( !SLOT->key )
908 SLOT->key = 1;
909 SLOT->phase = 0; /* restart Phase Generator */
910 SLOT->ssgn = (SLOT->ssg & 0x04) >> 1;
912 if ((type == TYPE_YM2612) || (type == TYPE_YM2608))
914 if( (SLOT->ar + SLOT->ksr) < 32+62 )
916 SLOT->state = EG_ATT; /* phase -> Attack */
918 else
920 /* directly switch to Decay */
921 SLOT->volume = MIN_ATT_INDEX;
922 SLOT->state = EG_DEC;
925 else
927 SLOT->state = EG_ATT;
932 INLINE void FM_KEYOFF(FM_CH *CH , int s )
934 FM_SLOT *SLOT = &CH->SLOT[s];
935 if( SLOT->key )
937 SLOT->key = 0;
938 if (SLOT->state>EG_REL)
939 SLOT->state = EG_REL;/* phase -> Release */
943 /* set algorithm connection */
944 static void setup_connection( FM_CH *CH, int ch )
946 INT32 *carrier = &out_fm[ch];
948 INT32 **om1 = &CH->connect1;
949 INT32 **om2 = &CH->connect3;
950 INT32 **oc1 = &CH->connect2;
952 INT32 **memc = &CH->mem_connect;
954 switch( CH->ALGO ){
955 case 0:
956 /* M1---C1---MEM---M2---C2---OUT */
957 *om1 = &c1;
958 *oc1 = &mem;
959 *om2 = &c2;
960 *memc= &m2;
961 break;
962 case 1:
963 /* M1------+-MEM---M2---C2---OUT */
964 /* C1-+ */
965 *om1 = &mem;
966 *oc1 = &mem;
967 *om2 = &c2;
968 *memc= &m2;
969 break;
970 case 2:
971 /* M1-----------------+-C2---OUT */
972 /* C1---MEM---M2-+ */
973 *om1 = &c2;
974 *oc1 = &mem;
975 *om2 = &c2;
976 *memc= &m2;
977 break;
978 case 3:
979 /* M1---C1---MEM------+-C2---OUT */
980 /* M2-+ */
981 *om1 = &c1;
982 *oc1 = &mem;
983 *om2 = &c2;
984 *memc= &c2;
985 break;
986 case 4:
987 /* M1---C1-+-OUT */
988 /* M2---C2-+ */
989 /* MEM: not used */
990 *om1 = &c1;
991 *oc1 = carrier;
992 *om2 = &c2;
993 *memc= &mem; /* store it anywhere where it will not be used */
994 break;
995 case 5:
996 /* +----C1----+ */
997 /* M1-+-MEM---M2-+-OUT */
998 /* +----C2----+ */
999 *om1 = 0; /* special mark */
1000 *oc1 = carrier;
1001 *om2 = carrier;
1002 *memc= &m2;
1003 break;
1004 case 6:
1005 /* M1---C1-+ */
1006 /* M2-+-OUT */
1007 /* C2-+ */
1008 /* MEM: not used */
1009 *om1 = &c1;
1010 *oc1 = carrier;
1011 *om2 = carrier;
1012 *memc= &mem; /* store it anywhere where it will not be used */
1013 break;
1014 case 7:
1015 /* M1-+ */
1016 /* C1-+-OUT */
1017 /* M2-+ */
1018 /* C2-+ */
1019 /* MEM: not used*/
1020 *om1 = carrier;
1021 *oc1 = carrier;
1022 *om2 = carrier;
1023 *memc= &mem; /* store it anywhere where it will not be used */
1024 break;
1027 CH->connect4 = carrier;
1030 /* set detune & multiple */
1031 INLINE void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
1033 SLOT->mul = (v&0x0f)? (v&0x0f)*2 : 1;
1034 SLOT->DT = ST->dt_tab[(v>>4)&7];
1035 CH->SLOT[SLOT1].Incr=-1;
1038 /* set total level */
1039 INLINE void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v)
1041 (void)CH;
1042 SLOT->tl = (v&0x7f)<<(ENV_BITS-7); /* 7bit TL */
1045 /* set attack rate & key scale */
1046 INLINE void set_ar_ksr(UINT8 type, FM_CH *CH,FM_SLOT *SLOT,int v)
1048 UINT8 old_KSR = SLOT->KSR;
1050 SLOT->ar = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1052 SLOT->KSR = 3-(v>>6);
1053 if (SLOT->KSR != old_KSR)
1055 CH->SLOT[SLOT1].Incr=-1;
1058 /* refresh Attack rate */
1059 if ((SLOT->ar + SLOT->ksr) < 32+62)
1061 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1062 if ((type == TYPE_YM2612) || (type == TYPE_YM2608))
1064 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1065 SLOT->eg_sel_ar = eg_rate_select2612[SLOT->ar + SLOT->ksr ];
1067 else
1069 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1072 else
1074 SLOT->eg_sh_ar = 0;
1075 SLOT->eg_sel_ar = 17*RATE_STEPS;
1079 /* set decay rate */
1080 INLINE void set_dr(UINT8 type, FM_SLOT *SLOT,int v)
1082 SLOT->d1r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1084 SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
1085 if ((type == TYPE_YM2612) || (type == TYPE_YM2608))
1087 SLOT->eg_sel_d1r= eg_rate_select2612[SLOT->d1r + SLOT->ksr];
1089 else
1091 SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];
1096 /* set sustain rate */
1097 INLINE void set_sr(UINT8 type, FM_SLOT *SLOT,int v)
1099 SLOT->d2r = (v&0x1f) ? 32 + ((v&0x1f)<<1) : 0;
1101 SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
1102 if ((type == TYPE_YM2612) || (type == TYPE_YM2608))
1104 SLOT->eg_sel_d2r= eg_rate_select2612[SLOT->d2r + SLOT->ksr];
1106 else
1108 SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];
1112 /* set release rate */
1113 INLINE void set_sl_rr(UINT8 type, FM_SLOT *SLOT,int v)
1115 SLOT->sl = sl_table[ v>>4 ];
1117 SLOT->rr = 34 + ((v&0x0f)<<2);
1119 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
1120 if ((type == TYPE_YM2612) || (type == TYPE_YM2608))
1122 SLOT->eg_sel_rr = eg_rate_select2612[SLOT->rr + SLOT->ksr];
1124 else
1126 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr];
1132 INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm)
1134 UINT32 p;
1136 p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + (pm<<15))) >> FREQ_SH ) & SIN_MASK ];
1138 if (p >= TL_TAB_LEN)
1139 return 0;
1140 return tl_tab[p];
1143 INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm)
1145 UINT32 p;
1147 p = (env<<3) + sin_tab[ ( ((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK ];
1149 if (p >= TL_TAB_LEN)
1150 return 0;
1151 return tl_tab[p];
1154 /* advance LFO to next sample */
1155 INLINE void advance_lfo(FM_OPN *OPN)
1157 UINT8 pos;
1159 if (OPN->lfo_inc) /* LFO enabled ? */
1161 OPN->lfo_cnt += OPN->lfo_inc;
1163 pos = (OPN->lfo_cnt >> LFO_SH) & 127;
1166 /* update AM when LFO output changes */
1168 /* actually I can't optimize is this way without rewritting chan_calc()
1169 to use chip->lfo_am instead of global lfo_am */
1172 /* triangle */
1173 /* AM: 0 to 126 step +2, 126 to 0 step -2 */
1174 if (pos<64)
1175 LFO_AM = (pos&63) * 2;
1176 else
1177 LFO_AM = 126 - ((pos&63) * 2);
1180 /* PM works with 4 times slower clock */
1181 pos >>= 2;
1182 /* update PM when LFO output changes */
1183 /*if (prev_pos != pos)*/ /* can't use global lfo_pm for this optimization, must be chip->lfo_pm instead*/
1185 LFO_PM = pos;
1189 else
1191 LFO_AM = 0;
1192 LFO_PM = 0;
1196 INLINE void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
1198 unsigned int out;
1199 unsigned int swap_flag = 0;
1200 unsigned int i;
1203 i = 4; /* four operators per channel */
1206 /* reset SSG-EG swap flag */
1207 swap_flag = 0;
1209 switch(SLOT->state)
1211 case EG_ATT: /* attack phase */
1212 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_ar)-1) ) )
1214 SLOT->volume += (~SLOT->volume *
1215 (eg_inc[SLOT->eg_sel_ar + ((OPN->eg_cnt>>SLOT->eg_sh_ar)&7)])
1216 ) >>4;
1218 if (SLOT->volume <= MIN_ATT_INDEX)
1220 SLOT->volume = MIN_ATT_INDEX;
1221 SLOT->state = EG_DEC;
1224 break;
1226 case EG_DEC: /* decay phase */
1227 if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608))
1229 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
1231 if (SLOT->ssg&0x08) /* SSG EG type envelope selected */
1233 SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1235 else
1237 SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1241 /* check transition even if no volume update: this fixes the case when SL = MIN_ATT_INDEX */
1242 if ( SLOT->volume >= (INT32)(SLOT->sl) )
1244 SLOT->volume = (INT32)(SLOT->sl);
1245 SLOT->state = EG_SUS;
1248 else
1250 if (SLOT->ssg&0x08) /* SSG EG type envelope selected */
1252 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
1254 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1256 if ( SLOT->volume >= (INT32)(SLOT->sl) )
1257 SLOT->state = EG_SUS;
1260 else
1262 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
1264 SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)];
1266 if ( SLOT->volume >= (INT32)(SLOT->sl) )
1267 SLOT->state = EG_SUS;
1271 break;
1273 case EG_SUS: /* sustain phase */
1274 if (SLOT->ssg&0x08) /* SSG EG type envelope selected */
1276 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
1278 if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608))
1280 SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1282 else
1284 SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1287 if ( SLOT->volume >= ENV_QUIET )
1289 if ((OPN->type != TYPE_YM2612) && (OPN->type != TYPE_YM2608))
1291 SLOT->volume = MAX_ATT_INDEX;
1294 if (SLOT->ssg&0x01) /* bit 0 = hold */
1296 if (SLOT->ssgn&1) /* have we swapped once ??? */
1298 /* yes, so do nothing, just hold current level */
1300 else
1301 swap_flag = (SLOT->ssg&0x02) | 1 ; /* bit 1 = alternate */
1304 else
1306 /* same as KEY-ON operation */
1308 /* restart of the Phase Generator should be here */
1309 SLOT->phase = 0;
1311 if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608))
1313 if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/)
1315 SLOT->state = EG_ATT; /* phase -> Attack */
1317 else
1319 /* Attack Rate is maximal: directly switch to Decay (or Substain) */
1320 SLOT->volume = MIN_ATT_INDEX;
1321 SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
1324 else
1326 /* phase -> Attack */
1327 SLOT->volume = 511;
1328 SLOT->state = EG_ATT;
1331 swap_flag = (SLOT->ssg&0x02); /* bit 1 = alternate */
1336 else
1338 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
1340 SLOT->volume += eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)];
1342 if ( SLOT->volume >= MAX_ATT_INDEX )
1344 SLOT->volume = MAX_ATT_INDEX;
1345 /* do not change SLOT->state (verified on real chip) */
1350 break;
1352 case EG_REL: /* release phase */
1353 if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_rr)-1) ) )
1355 /* SSG-EG affects Release phase also (Nemesis) */
1356 if ((SLOT->ssg&0x08) && ((OPN->type = TYPE_YM2612) || (OPN->type = TYPE_YM2608)))
1358 SLOT->volume += 6 * eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)];
1360 else
1362 SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)];
1365 if ( SLOT->volume >= MAX_ATT_INDEX )
1367 SLOT->volume = MAX_ATT_INDEX;
1368 SLOT->state = EG_OFF;
1371 break;
1375 out = ((UINT32)SLOT->volume);
1377 /* negate output (changes come from alternate bit, init comes from attack bit) */
1378 if ((SLOT->ssg&0x08) && (SLOT->ssgn&2) && (SLOT->state > EG_REL))
1379 out ^= MAX_ATT_INDEX;
1381 /* we need to store the result here because we are going to change ssgn
1382 in next instruction */
1383 SLOT->vol_out = out + SLOT->tl;
1385 /* reverse SLOT inversion flag */
1386 SLOT->ssgn ^= swap_flag;
1388 SLOT++;
1389 i--;
1390 }while (i);
1396 #define volume_calc(OP) ((OP)->vol_out + (AM & (OP)->AMmask))
1398 INLINE void update_phase_lfo_slot(FM_OPN *OPN, FM_SLOT *SLOT, INT32 pms, UINT32 block_fnum)
1400 UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
1401 INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + pms + LFO_PM ];
1403 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
1405 UINT8 blk;
1406 UINT32 fn;
1407 int kc, fc;
1409 block_fnum = block_fnum*2 + lfo_fn_table_index_offset;
1411 blk = (block_fnum&0x7000) >> 12;
1412 fn = block_fnum & 0xfff;
1414 /* keyscale code */
1415 kc = (blk<<2) | opn_fktable[fn >> 8];
1417 /* phase increment counter */
1418 fc = (OPN->fn_table[fn]>>(7-blk)) + SLOT->DT[kc];
1420 /* detects frequency overflow (credits to Nemesis) */
1421 if (fc < 0) fc += OPN->fn_max;
1423 /* update phase */
1424 SLOT->phase += (fc * SLOT->mul) >> 1;
1426 else /* LFO phase modulation = zero */
1428 SLOT->phase += SLOT->Incr;
1432 INLINE void update_phase_lfo_channel(FM_OPN *OPN, FM_CH *CH)
1434 UINT32 block_fnum = CH->block_fnum;
1436 UINT32 fnum_lfo = ((block_fnum & 0x7f0) >> 4) * 32 * 8;
1437 INT32 lfo_fn_table_index_offset = lfo_pm_table[ fnum_lfo + CH->pms + LFO_PM ];
1439 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
1441 UINT8 blk;
1442 UINT32 fn;
1443 int kc, fc, finc;
1445 block_fnum = block_fnum*2 + lfo_fn_table_index_offset;
1447 blk = (block_fnum&0x7000) >> 12;
1448 fn = block_fnum & 0xfff;
1450 /* keyscale code */
1451 kc = (blk<<2) | opn_fktable[fn >> 8];
1453 /* phase increment counter */
1454 fc = (OPN->fn_table[fn]>>(7-blk));
1456 /* detects frequency overflow (credits to Nemesis) */
1457 finc = fc + CH->SLOT[SLOT1].DT[kc];
1459 if (finc < 0) finc += OPN->fn_max;
1460 CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1;
1462 finc = fc + CH->SLOT[SLOT2].DT[kc];
1463 if (finc < 0) finc += OPN->fn_max;
1464 CH->SLOT[SLOT2].phase += (finc*CH->SLOT[SLOT2].mul) >> 1;
1466 finc = fc + CH->SLOT[SLOT3].DT[kc];
1467 if (finc < 0) finc += OPN->fn_max;
1468 CH->SLOT[SLOT3].phase += (finc*CH->SLOT[SLOT3].mul) >> 1;
1470 finc = fc + CH->SLOT[SLOT4].DT[kc];
1471 if (finc < 0) finc += OPN->fn_max;
1472 CH->SLOT[SLOT4].phase += (finc*CH->SLOT[SLOT4].mul) >> 1;
1474 else /* LFO phase modulation = zero */
1476 CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
1477 CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
1478 CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
1479 CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
1483 INLINE void chan_calc(FM_OPN *OPN, FM_CH *CH, int chnum)
1485 unsigned int eg_out;
1487 UINT32 AM = LFO_AM >> CH->ams;
1490 m2 = c1 = c2 = mem = 0;
1492 *CH->mem_connect = CH->mem_value; /* restore delayed sample (MEM) value to m2 or c2 */
1494 eg_out = volume_calc(&CH->SLOT[SLOT1]);
1496 INT32 out = CH->op1_out[0] + CH->op1_out[1];
1497 CH->op1_out[0] = CH->op1_out[1];
1499 if( !CH->connect1 ){
1500 /* algorithm 5 */
1501 mem = c1 = c2 = CH->op1_out[0];
1503 else
1505 /* other algorithms */
1506 *CH->connect1 += CH->op1_out[0];
1509 CH->op1_out[1] = 0;
1510 if( eg_out < ENV_QUIET ) /* SLOT 1 */
1512 if (!CH->FB)
1513 out=0;
1515 CH->op1_out[1] = op_calc1(CH->SLOT[SLOT1].phase, eg_out, (out<<CH->FB) );
1519 eg_out = volume_calc(&CH->SLOT[SLOT3]);
1520 if( eg_out < ENV_QUIET ) /* SLOT 3 */
1521 *CH->connect3 += op_calc(CH->SLOT[SLOT3].phase, eg_out, m2);
1523 eg_out = volume_calc(&CH->SLOT[SLOT2]);
1524 if( eg_out < ENV_QUIET ) /* SLOT 2 */
1525 *CH->connect2 += op_calc(CH->SLOT[SLOT2].phase, eg_out, c1);
1527 eg_out = volume_calc(&CH->SLOT[SLOT4]);
1528 if( eg_out < ENV_QUIET ) /* SLOT 4 */
1529 *CH->connect4 += op_calc(CH->SLOT[SLOT4].phase, eg_out, c2);
1532 /* store current MEM */
1533 CH->mem_value = mem;
1535 /* update phase counters AFTER output calculations */
1536 if(CH->pms)
1538 /* add support for 3 slot mode */
1539 if ((OPN->ST.mode & 0xC0) && (chnum == 2))
1541 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT1], CH->pms, OPN->SL3.block_fnum[1]);
1542 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT2], CH->pms, OPN->SL3.block_fnum[2]);
1543 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT3], CH->pms, OPN->SL3.block_fnum[0]);
1544 update_phase_lfo_slot(OPN, &CH->SLOT[SLOT4], CH->pms, CH->block_fnum);
1546 else update_phase_lfo_channel(OPN, CH);
1548 else /* no LFO phase modulation */
1550 CH->SLOT[SLOT1].phase += CH->SLOT[SLOT1].Incr;
1551 CH->SLOT[SLOT2].phase += CH->SLOT[SLOT2].Incr;
1552 CH->SLOT[SLOT3].phase += CH->SLOT[SLOT3].Incr;
1553 CH->SLOT[SLOT4].phase += CH->SLOT[SLOT4].Incr;
1557 /* update phase increment and envelope generator */
1558 INLINE void refresh_fc_eg_slot(FM_OPN *OPN, FM_SLOT *SLOT , int fc , int kc )
1560 int ksr = kc >> SLOT->KSR;
1562 fc += SLOT->DT[kc];
1564 /* detects frequency overflow (credits to Nemesis) */
1565 if (fc < 0) fc += OPN->fn_max;
1567 /* (frequency) phase increment counter */
1568 SLOT->Incr = (fc * SLOT->mul) >> 1;
1570 if( SLOT->ksr != ksr )
1572 SLOT->ksr = ksr;
1574 /* calculate envelope generator rates */
1575 if ((SLOT->ar + SLOT->ksr) < 32+62)
1577 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1578 if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608))
1580 SLOT->eg_sel_ar = eg_rate_select2612[SLOT->ar + SLOT->ksr ];
1582 else
1584 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1587 else
1589 SLOT->eg_sh_ar = 0;
1590 SLOT->eg_sel_ar = 17*RATE_STEPS;
1593 SLOT->eg_sh_d1r = eg_rate_shift [SLOT->d1r + SLOT->ksr];
1594 SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr];
1595 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr];
1597 if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608))
1599 SLOT->eg_sel_d1r= eg_rate_select2612[SLOT->d1r + SLOT->ksr];
1600 SLOT->eg_sel_d2r= eg_rate_select2612[SLOT->d2r + SLOT->ksr];
1601 SLOT->eg_sel_rr = eg_rate_select2612[SLOT->rr + SLOT->ksr];
1603 else
1605 SLOT->eg_sel_d1r= eg_rate_select[SLOT->d1r + SLOT->ksr];
1606 SLOT->eg_sel_d2r= eg_rate_select[SLOT->d2r + SLOT->ksr];
1607 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr];
1612 /* update phase increment counters */
1613 /* Changed from INLINE to static to work around gcc 4.2.1 codegen bug */
1614 static void refresh_fc_eg_chan(FM_OPN *OPN, FM_CH *CH )
1616 if( CH->SLOT[SLOT1].Incr==-1){
1617 int fc = CH->fc;
1618 int kc = CH->kcode;
1619 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT1] , fc , kc );
1620 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT2] , fc , kc );
1621 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT3] , fc , kc );
1622 refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT4] , fc , kc );
1626 /* initialize time tables */
1627 static void init_timetables( FM_ST *ST , const UINT8 *dttable )
1629 int i,d;
1630 double rate;
1632 #if 0
1633 logerror("FM.C: samplerate=%8i chip clock=%8i freqbase=%f \n",
1634 ST->rate, ST->clock, ST->freqbase );
1635 #endif
1637 /* DeTune table */
1638 for (d = 0;d <= 3;d++){
1639 for (i = 0;i <= 31;i++){
1640 rate = ((double)dttable[d*32 + i]) * SIN_LEN * ST->freqbase * (1<<FREQ_SH) / ((double)(1<<20));
1641 ST->dt_tab[d][i] = (INT32) rate;
1642 ST->dt_tab[d+4][i] = -ST->dt_tab[d][i];
1643 #if 0
1644 logerror("FM.C: DT [%2i %2i] = %8x \n", d, i, ST->dt_tab[d][i] );
1645 #endif
1652 static void reset_channels( FM_ST *ST , FM_CH *CH , int num )
1654 int c,s;
1656 ST->mode = 0; /* normal mode */
1657 ST->TA = 0;
1658 ST->TAC = 0;
1659 ST->TB = 0;
1660 ST->TBC = 0;
1662 for( c = 0 ; c < num ; c++ )
1664 CH[c].fc = 0;
1665 for(s = 0 ; s < 4 ; s++ )
1667 CH[c].SLOT[s].ssg = 0;
1668 CH[c].SLOT[s].ssgn = 0;
1669 CH[c].SLOT[s].state= EG_OFF;
1670 CH[c].SLOT[s].volume = MAX_ATT_INDEX;
1671 CH[c].SLOT[s].vol_out= MAX_ATT_INDEX;
1676 /* initialize generic tables */
1677 static int init_tables(void)
1679 signed int i,x;
1680 signed int n;
1681 double o,m;
1683 for (x=0; x<TL_RES_LEN; x++)
1685 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);
1686 m = floor(m);
1688 /* we never reach (1<<16) here due to the (x+1) */
1689 /* result fits within 16 bits at maximum */
1691 n = (int)m; /* 16 bits here */
1692 n >>= 4; /* 12 bits here */
1693 if (n&1) /* round to nearest */
1694 n = (n>>1)+1;
1695 else
1696 n = n>>1;
1697 /* 11 bits here (rounded) */
1698 n <<= 2; /* 13 bits here (as in real chip) */
1699 tl_tab[ x*2 + 0 ] = n;
1700 tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ];
1702 for (i=1; i<13; i++)
1704 tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i;
1705 tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ];
1707 #if 0
1708 logerror("tl %04i", x);
1709 for (i=0; i<13; i++)
1710 logerror(", [%02i] %4x", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ]);
1711 logerror("\n");
1713 #endif
1715 /*logerror("FM.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
1718 for (i=0; i<SIN_LEN; i++)
1720 /* non-standard sinus */
1721 m = sin( ((i*2)+1) * PI / SIN_LEN ); /* checked against the real chip */
1723 /* we never reach zero here due to ((i*2)+1) */
1725 if (m>0.0)
1726 o = 8*log(1.0/m)/log(2); /* convert to 'decibels' */
1727 else
1728 o = 8*log(-1.0/m)/log(2); /* convert to 'decibels' */
1730 o = o / (ENV_STEP/4);
1732 n = (int)(2.0*o);
1733 if (n&1) /* round to nearest */
1734 n = (n>>1)+1;
1735 else
1736 n = n>>1;
1738 sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
1739 /*logerror("FM.C: sin [%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[i],tl_tab[sin_tab[i]]);*/
1742 /*logerror("FM.C: ENV_QUIET= %08x\n",ENV_QUIET );*/
1745 /* build LFO PM modulation table */
1746 for(i = 0; i < 8; i++) /* 8 PM depths */
1748 UINT8 fnum;
1749 for (fnum=0; fnum<128; fnum++) /* 7 bits meaningful of F-NUMBER */
1751 UINT8 value;
1752 UINT8 step;
1753 UINT32 offset_depth = i;
1754 UINT32 offset_fnum_bit;
1755 UINT32 bit_tmp;
1757 for (step=0; step<8; step++)
1759 value = 0;
1760 for (bit_tmp=0; bit_tmp<7; bit_tmp++) /* 7 bits */
1762 if (fnum & (1<<bit_tmp)) /* only if bit "bit_tmp" is set */
1764 offset_fnum_bit = bit_tmp * 8;
1765 value += lfo_pm_output[offset_fnum_bit + offset_depth][step];
1768 lfo_pm_table[(fnum*32*8) + (i*32) + step + 0] = value;
1769 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+ 8] = value;
1770 lfo_pm_table[(fnum*32*8) + (i*32) + step +16] = -value;
1771 lfo_pm_table[(fnum*32*8) + (i*32) +(step^7)+24] = -value;
1773 #if 0
1774 logerror("LFO depth=%1x FNUM=%04x (<<4=%4x): ", i, fnum, fnum<<4);
1775 for (step=0; step<16; step++) /* dump only positive part of waveforms */
1776 logerror("%02x ", lfo_pm_table[(fnum*32*8) + (i*32) + step] );
1777 logerror("\n");
1778 #endif
1785 #ifdef SAVE_SAMPLE
1786 sample[0]=fopen("sampsum.pcm","wb");
1787 #endif
1789 return 1;
1795 static void FMCloseTable( void )
1797 #ifdef SAVE_SAMPLE
1798 fclose(sample[0]);
1799 #endif
1800 return;
1804 /* CSM Key Controll */
1805 INLINE void CSMKeyControll(UINT8 type, FM_CH *CH)
1807 /* all key on then off (only for operators which were OFF!) */
1808 if (!CH->SLOT[SLOT1].key)
1810 FM_KEYON(type, CH,SLOT1);
1811 FM_KEYOFF(CH, SLOT1);
1813 if (!CH->SLOT[SLOT2].key)
1815 FM_KEYON(type, CH,SLOT2);
1816 FM_KEYOFF(CH, SLOT2);
1818 if (!CH->SLOT[SLOT3].key)
1820 FM_KEYON(type, CH,SLOT3);
1821 FM_KEYOFF(CH, SLOT3);
1823 if (!CH->SLOT[SLOT4].key)
1825 FM_KEYON(type, CH,SLOT4);
1826 FM_KEYOFF(CH, SLOT4);
1830 #ifdef _STATE_H
1831 /* FM channel save , internal state only */
1832 static void FMsave_state_channel(const char *name,int num,FM_CH *CH,int num_ch)
1834 int slot , ch;
1835 char state_name[20];
1836 const char slot_array[4] = { 1 , 3 , 2 , 4 };
1838 for(ch=0;ch<num_ch;ch++,CH++)
1840 /* channel */
1841 sprintf(state_name,"%s.CH%d",name,ch);
1842 state_save_register_INT32(state_name, num, "feedback" , CH->op1_out , 2);
1843 state_save_register_UINT32(state_name, num, "phasestep" , &CH->fc , 1);
1844 /* slots */
1845 for(slot=0;slot<4;slot++)
1847 FM_SLOT *SLOT = &CH->SLOT[slot];
1849 sprintf(state_name,"%s.CH%d.SLOT%d",name,ch,slot_array[slot]);
1850 state_save_register_UINT32(state_name, num, "phasecount" , &SLOT->phase, 1);
1851 state_save_register_UINT8 (state_name, num, "state" , &SLOT->state, 1);
1852 state_save_register_INT32 (state_name, num, "volume" , &SLOT->volume, 1);
1857 static void FMsave_state_st(const char *state_name,int num,FM_ST *ST)
1859 #if FM_BUSY_FLAG_SUPPORT
1860 state_save_register_double(state_name, num, "BusyExpire", &ST->BusyExpire , 1);
1861 #endif
1862 state_save_register_UINT8 (state_name, num, "address" , &ST->address , 1);
1863 state_save_register_UINT8 (state_name, num, "IRQ" , &ST->irq , 1);
1864 state_save_register_UINT8 (state_name, num, "IRQ MASK" , &ST->irqmask , 1);
1865 state_save_register_UINT8 (state_name, num, "status" , &ST->status , 1);
1866 state_save_register_UINT32(state_name, num, "mode" , &ST->mode , 1);
1867 state_save_register_UINT8 (state_name, num, "prescaler" , &ST->prescaler_sel , 1);
1868 state_save_register_UINT8 (state_name, num, "freq latch", &ST->fn_h , 1);
1869 state_save_register_int (state_name, num, "TIMER A" , &ST->TA );
1870 state_save_register_int (state_name, num, "TIMER Acnt", &ST->TAC );
1871 state_save_register_UINT8 (state_name, num, "TIMER B" , &ST->TB , 1);
1872 state_save_register_int (state_name, num, "TIMER Bcnt", &ST->TBC );
1874 #endif /* _STATE_H */
1876 #if BUILD_OPN
1880 /* prescaler set (and make time tables) */
1881 static void OPNSetPres(FM_OPN *OPN , int pres , int TimerPres, int SSGpres)
1883 int i;
1885 /* frequency base */
1886 OPN->ST.freqbase = (OPN->ST.rate) ? ((double)OPN->ST.clock / OPN->ST.rate) / pres : 0;
1888 #if 0
1889 OPN->ST.rate = (double)OPN->ST.clock / pres;
1890 OPN->ST.freqbase = 1.0;
1891 #endif
1893 OPN->eg_timer_add = (1<<EG_SH) * OPN->ST.freqbase;
1894 OPN->eg_timer_overflow = ( 3 ) * (1<<EG_SH);
1897 /* Timer base time */
1898 OPN->ST.TimerBase = 1.0/((double)OPN->ST.clock / (double)TimerPres);
1900 #if FM_SSG_PRESCALER
1901 /* SSG part prescaler set */
1902 if( SSGpres ) SSGClk( OPN->ST.index, OPN->ST.clock * 2 / SSGpres );
1903 #else
1904 (void)SSGpres;
1905 #endif
1907 /* make time tables */
1908 init_timetables( &OPN->ST, dt_tab );
1910 /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
1911 but LFO works with one more bit of a precision so we really need 4096 elements */
1912 /* calculate fnumber -> increment counter table */
1913 for(i = 0; i < 4096; i++)
1915 /* freq table for octave 7 */
1916 /* OPN phase increment counter = 20bit */
1917 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 */
1918 #if 0
1919 logerror("FM.C: fn_table[%4i] = %08x (dec=%8i)\n",
1920 i, OPN->fn_table[i]>>6,OPN->fn_table[i]>>6 );
1921 #endif
1924 /* maximal frequency is required for Phase overflow calculation, register size is 17 bits (Nemesis) */
1925 OPN->fn_max = (UINT32)( (double)0x20000 * OPN->ST.freqbase * (1<<(FREQ_SH-10)) );
1927 /* LFO freq. table */
1928 for(i = 0; i < 8; i++)
1930 /* Amplitude modulation: 64 output levels (triangle waveform); 1 level lasts for one of "lfo_samples_per_step" samples */
1931 /* Phase modulation: one entry from lfo_pm_output lasts for one of 4 * "lfo_samples_per_step" samples */
1932 OPN->lfo_freq[i] = (1.0 / lfo_samples_per_step[i]) * (1<<LFO_SH) * OPN->ST.freqbase;
1933 #if 0
1934 logerror("FM.C: lfo_freq[%i] = %08x (dec=%8i)\n",
1935 i, OPN->lfo_freq[i],OPN->lfo_freq[i] );
1936 #endif
1942 /* write a OPN mode register 0x20-0x2f */
1943 static void OPNWriteMode(FM_OPN *OPN, int r, int v)
1945 UINT8 c;
1946 FM_CH *CH;
1948 switch(r){
1949 case 0x21: /* Test */
1950 break;
1951 case 0x22: /* LFO FREQ (YM2608/YM2610/YM2610B/YM2612) */
1952 if( OPN->type & TYPE_LFOPAN )
1954 if (v&0x08) /* LFO enabled ? */
1956 OPN->lfo_inc = OPN->lfo_freq[v&7];
1958 else
1960 OPN->lfo_inc = 0;
1963 break;
1964 case 0x24: /* timer A High 8*/
1965 OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
1966 break;
1967 case 0x25: /* timer A Low 2*/
1968 OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
1969 break;
1970 case 0x26: /* timer B */
1971 OPN->ST.TB = v;
1972 break;
1973 case 0x27: /* mode, timer control */
1974 set_timers( &(OPN->ST),OPN->ST.index,v );
1975 break;
1976 case 0x28: /* key on / off */
1977 c = v & 0x03;
1978 if( c == 3 ) break;
1979 if( (v&0x04) && (OPN->type & TYPE_6CH) ) c+=3;
1980 CH = OPN->P_CH;
1981 CH = &CH[c];
1982 if(v&0x10) FM_KEYON(OPN->type, CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
1983 if(v&0x20) FM_KEYON(OPN->type, CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
1984 if(v&0x40) FM_KEYON(OPN->type, CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
1985 if(v&0x80) FM_KEYON(OPN->type, CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
1986 break;
1990 /* write a OPN register (0x30-0xff) */
1991 static void OPNWriteReg(FM_OPN *OPN, int r, int v)
1993 FM_CH *CH;
1994 FM_SLOT *SLOT;
1996 UINT8 c = OPN_CHAN(r);
1998 if (c == 3) return; /* 0xX3,0xX7,0xXB,0xXF */
2000 if (r >= 0x100) c+=3;
2002 CH = OPN->P_CH;
2003 CH = &CH[c];
2005 SLOT = &(CH->SLOT[OPN_SLOT(r)]);
2007 switch( r & 0xf0 ) {
2008 case 0x30: /* DET , MUL */
2009 set_det_mul(&OPN->ST,CH,SLOT,v);
2010 break;
2012 case 0x40: /* TL */
2013 set_tl(CH,SLOT,v);
2014 break;
2016 case 0x50: /* KS, AR */
2017 set_ar_ksr(OPN->type, CH,SLOT,v);
2018 break;
2020 case 0x60: /* bit7 = AM ENABLE, DR */
2021 set_dr(OPN->type, SLOT,v);
2023 if(OPN->type & TYPE_LFOPAN) /* YM2608/2610/2610B/2612 */
2025 SLOT->AMmask = (v&0x80) ? ~0 : 0;
2027 break;
2029 case 0x70: /* SR */
2030 set_sr(OPN->type, SLOT,v);
2031 break;
2033 case 0x80: /* SL, RR */
2034 set_sl_rr(OPN->type, SLOT,v);
2035 break;
2037 case 0x90: /* SSG-EG */
2038 SLOT->ssg = v&0x0f;
2039 SLOT->ssgn = (v&0x04)>>1; /* bit 1 in ssgn = attack */
2041 /* SSG-EG envelope shapes :
2043 E AtAlH
2044 1 0 0 0 \\\\
2046 1 0 0 1 \___
2048 1 0 1 0 \/\/
2050 1 0 1 1 \
2052 1 1 0 0 ////
2054 1 1 0 1 /
2056 1 1 1 0 /\/\
2058 1 1 1 1 /___
2061 E = SSG-EG enable
2064 The shapes are generated using Attack, Decay and Sustain phases.
2066 Each single character in the diagrams above represents this whole
2067 sequence:
2069 - when KEY-ON = 1, normal Attack phase is generated (*without* any
2070 difference when compared to normal mode),
2072 - later, when envelope level reaches minimum level (max volume),
2073 the EG switches to Decay phase (which works with bigger steps
2074 when compared to normal mode - see below),
2076 - later when envelope level passes the SL level,
2077 the EG swithes to Sustain phase (which works with bigger steps
2078 when compared to normal mode - see below),
2080 - finally when envelope level reaches maximum level (min volume),
2081 the EG switches to Attack phase again (depends on actual waveform).
2083 Important is that when switch to Attack phase occurs, the phase counter
2084 of that operator will be zeroed-out (as in normal KEY-ON) but not always.
2085 (I havent found the rule for that - perhaps only when the output level is low)
2087 The difference (when compared to normal Envelope Generator mode) is
2088 that the resolution in Decay and Sustain phases is 4 times lower;
2089 this results in only 256 steps instead of normal 1024.
2090 In other words:
2091 when SSG-EG is disabled, the step inside of the EG is one,
2092 when SSG-EG is enabled, the step is four (in Decay and Sustain phases).
2094 Times between the level changes are the same in both modes.
2097 Important:
2098 Decay 1 Level (so called SL) is compared to actual SSG-EG output, so
2099 it is the same in both SSG and no-SSG modes, with this exception:
2101 when the SSG-EG is enabled and is generating raising levels
2102 (when the EG output is inverted) the SL will be found at wrong level !!!
2103 For example, when SL=02:
2104 0 -6 = -6dB in non-inverted EG output
2105 96-6 = -90dB in inverted EG output
2106 Which means that EG compares its level to SL as usual, and that the
2107 output is simply inverted afterall.
2110 The Yamaha's manuals say that AR should be set to 0x1f (max speed).
2111 That is not necessary, but then EG will be generating Attack phase.
2116 break;
2118 case 0xa0:
2119 switch( OPN_SLOT(r) ){
2120 case 0: /* 0xa0-0xa2 : FNUM1 */
2122 UINT32 fn = (((UINT32)( (OPN->ST.fn_h)&7))<<8) + v;
2123 UINT8 blk = OPN->ST.fn_h>>3;
2124 /* keyscale code */
2125 CH->kcode = (blk<<2) | opn_fktable[fn >> 7];
2126 /* phase increment counter */
2127 CH->fc = OPN->fn_table[fn*2]>>(7-blk);
2129 /* store fnum in clear form for LFO PM calculations */
2130 CH->block_fnum = (blk<<11) | fn;
2132 CH->SLOT[SLOT1].Incr=-1;
2134 break;
2135 case 1: /* 0xa4-0xa6 : FNUM2,BLK */
2136 OPN->ST.fn_h = v&0x3f;
2137 break;
2138 case 2: /* 0xa8-0xaa : 3CH FNUM1 */
2139 if(r < 0x100)
2141 UINT32 fn = (((UINT32)(OPN->SL3.fn_h&7))<<8) + v;
2142 UINT8 blk = OPN->SL3.fn_h>>3;
2143 /* keyscale code */
2144 OPN->SL3.kcode[c]= (blk<<2) | opn_fktable[fn >> 7];
2145 /* phase increment counter */
2146 OPN->SL3.fc[c] = OPN->fn_table[fn*2]>>(7-blk);
2147 OPN->SL3.block_fnum[c] = (blk<<11) | fn;
2148 (OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
2150 break;
2151 case 3: /* 0xac-0xae : 3CH FNUM2,BLK */
2152 if(r < 0x100)
2153 OPN->SL3.fn_h = v&0x3f;
2154 break;
2156 break;
2158 case 0xb0:
2159 switch( OPN_SLOT(r) ){
2160 case 0: /* 0xb0-0xb2 : FB,ALGO */
2162 int feedback = (v>>3)&7;
2163 CH->ALGO = v&7;
2164 CH->FB = feedback ? feedback+6 : 0;
2165 setup_connection( CH, c );
2167 break;
2168 case 1: /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2610B/YM2610/YM2608) */
2169 if( OPN->type & TYPE_LFOPAN)
2171 /* b0-2 PMS */
2172 CH->pms = (v & 7) * 32; /* CH->pms = PM depth * 32 (index in lfo_pm_table) */
2174 /* b4-5 AMS */
2175 CH->ams = lfo_ams_depth_shift[(v>>4) & 0x03];
2177 /* PAN : b7 = L, b6 = R */
2178 OPN->pan[ c*2 ] = (v & 0x80) ? ~0 : 0;
2179 OPN->pan[ c*2+1 ] = (v & 0x40) ? ~0 : 0;
2182 break;
2184 break;
2188 #endif /* BUILD_OPN */
2190 #if BUILD_OPN_PRESCALER
2192 prescaler circuit (best guess to verified chip behaviour)
2194 +--------------+ +-sel2-+
2195 | +--|in20 |
2196 +---+ | +-sel1-+ | |
2197 M-CLK -+-|1/2|-+--|in10 | +---+ | out|--INT_CLOCK
2198 | +---+ | out|-|1/3|-|in21 |
2199 +----------|in11 | +---+ +------+
2200 +------+
2202 reg.2d : sel2 = in21 (select sel2)
2203 reg.2e : sel1 = in11 (select sel1)
2204 reg.2f : sel1 = in10 , sel2 = in20 (clear selector)
2205 reset : sel1 = in11 , sel2 = in21 (clear both)
2208 void OPNPrescaler_w(FM_OPN *OPN , int addr, int pre_divider)
2210 static const int opn_pres[4] = { 2*12 , 2*12 , 6*12 , 3*12 };
2211 static const int ssg_pres[4] = { 1 , 1 , 4 , 2 };
2212 int sel;
2214 switch(addr)
2216 case 0: /* when reset */
2217 OPN->ST.prescaler_sel = 2;
2218 break;
2219 case 1: /* when postload */
2220 break;
2221 case 0x2d: /* divider sel : select 1/1 for 1/3line */
2222 OPN->ST.prescaler_sel |= 0x02;
2223 break;
2224 case 0x2e: /* divider sel , select 1/3line for output */
2225 OPN->ST.prescaler_sel |= 0x01;
2226 break;
2227 case 0x2f: /* divider sel , clear both selector to 1/2,1/2 */
2228 OPN->ST.prescaler_sel = 0;
2229 break;
2231 sel = OPN->ST.prescaler_sel & 3;
2232 /* update prescaler */
2233 OPNSetPres( OPN, opn_pres[sel]*pre_divider,
2234 opn_pres[sel]*pre_divider,
2235 ssg_pres[sel]*pre_divider );
2237 #endif /* BUILD_OPN_PRESCALER */
2239 #if BUILD_YM2203
2240 /*****************************************************************************/
2241 /* YM2203 local section */
2242 /*****************************************************************************/
2244 /* here's the virtual YM2203(OPN) */
2245 typedef struct
2247 #ifdef _STATE_H
2248 UINT8 REGS[256]; /* registers */
2249 #endif
2250 FM_OPN OPN; /* OPN state */
2251 FM_CH CH[3]; /* channel state */
2252 } YM2203;
2254 static YM2203 *FM2203=NULL; /* array of YM2203's */
2255 static int YM2203NumChips; /* number of chips */
2257 /* Generate samples for one of the YM2203s */
2258 void YM2203UpdateOne(int num, INT16 *buffer, int length)
2260 YM2203 *F2203 = &(FM2203[num]);
2261 FM_OPN *OPN = &(FM2203[num].OPN);
2262 int i;
2263 FMSAMPLE *buf = buffer;
2265 cur_chip = (void *)F2203;
2266 State = &F2203->OPN.ST;
2267 cch[0] = &F2203->CH[0];
2268 cch[1] = &F2203->CH[1];
2269 cch[2] = &F2203->CH[2];
2272 /* refresh PG and EG */
2273 refresh_fc_eg_chan( OPN, cch[0] );
2274 refresh_fc_eg_chan( OPN, cch[1] );
2275 if( (State->mode & 0xc0) )
2277 /* 3SLOT MODE */
2278 if( cch[2]->SLOT[SLOT1].Incr==-1)
2280 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2281 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2282 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2283 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2285 }else refresh_fc_eg_chan( OPN, cch[2] );
2288 /* YM2203 doesn't have LFO so we must keep these globals at 0 level */
2289 LFO_AM = 0;
2290 LFO_PM = 0;
2292 /* buffering */
2293 for (i=0; i < length ; i++)
2295 /* clear outputs */
2296 out_fm[0] = 0;
2297 out_fm[1] = 0;
2298 out_fm[2] = 0;
2300 /* advance envelope generator */
2301 OPN->eg_timer += OPN->eg_timer_add;
2302 while (OPN->eg_timer >= OPN->eg_timer_overflow)
2304 OPN->eg_timer -= OPN->eg_timer_overflow;
2305 OPN->eg_cnt++;
2307 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
2308 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
2309 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
2312 /* calculate FM */
2313 chan_calc(OPN, cch[0], 0 );
2314 chan_calc(OPN, cch[1], 1 );
2315 chan_calc(OPN, cch[2], 2 );
2317 /* buffering */
2319 int lt;
2321 lt = out_fm[0] + out_fm[1] + out_fm[2];
2323 lt >>= FINAL_SH;
2325 Limit( lt , MAXOUT, MINOUT );
2327 #ifdef SAVE_SAMPLE
2328 SAVE_ALL_CHANNELS
2329 #endif
2331 /* buffering */
2332 buf[i] = lt;
2335 /* timer A control */
2336 INTERNAL_TIMER_A( State , cch[2] )
2338 INTERNAL_TIMER_B(State,length)
2341 /* ---------- reset one of chip ---------- */
2342 void YM2203ResetChip(int num)
2344 int i;
2345 FM_OPN *OPN = &(FM2203[num].OPN);
2347 /* Reset Prescaler */
2348 OPNPrescaler_w(OPN, 0 , 1 );
2349 /* reset SSG section */
2350 SSGReset(OPN->ST.index);
2351 /* status clear */
2352 FM_IRQMASK_SET(&OPN->ST,0x03);
2353 FM_BUSY_CLEAR(&OPN->ST);
2354 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2356 OPN->eg_timer = 0;
2357 OPN->eg_cnt = 0;
2359 FM_STATUS_RESET(&OPN->ST, 0xff);
2361 reset_channels( &OPN->ST , FM2203[num].CH , 3 );
2362 /* reset OPerator paramater */
2363 for(i = 0xb2 ; i >= 0x30 ; i-- ) OPNWriteReg(OPN,i,0);
2364 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2367 #ifdef _STATE_H
2368 static void YM2203_postload(void)
2370 int num , r;
2372 for(num=0;num<YM2203NumChips;num++)
2374 /* prescaler */
2375 OPNPrescaler_w(&FM2203[num].OPN,1,1);
2377 /* SSG registers */
2378 for(r=0;r<16;r++)
2380 SSGWrite(num,0,r);
2381 SSGWrite(num,1,FM2203[num].REGS[r]);
2384 /* OPN registers */
2385 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
2386 for(r=0x30;r<0x9e;r++)
2387 if((r&3) != 3)
2388 OPNWriteReg(&FM2203[num].OPN,r,FM2203[num].REGS[r]);
2389 /* FB / CONNECT , L / R / AMS / PMS */
2390 for(r=0xb0;r<0xb6;r++)
2391 if((r&3) != 3)
2392 OPNWriteReg(&FM2203[num].OPN,r,FM2203[num].REGS[r]);
2394 /* channels */
2395 /*FM_channel_postload(FM2203[num].CH,3);*/
2397 cur_chip = NULL;
2400 static void YM2203_save_state(void)
2402 int num;
2403 const char statename[] = "YM2203";
2405 for(num=0;num<YM2203NumChips;num++)
2407 state_save_register_UINT8 (statename, num, "regs" , FM2203[num].REGS , 256);
2408 FMsave_state_st(statename,num,&FM2203[num].OPN.ST);
2409 FMsave_state_channel(statename,num,FM2203[num].CH,3);
2410 /* 3slots */
2411 state_save_register_UINT32 (statename, num, "slot3fc" , FM2203[num].OPN.SL3.fc , 3);
2412 state_save_register_UINT8 (statename, num, "slot3fh" , &FM2203[num].OPN.SL3.fn_h , 1);
2413 state_save_register_UINT8 (statename, num, "slot3kc" , FM2203[num].OPN.SL3.kcode , 3);
2415 state_save_register_func_postload(YM2203_postload);
2417 #endif /* _STATE_H */
2419 /* ---------- Initialize YM2203 emulator(s) ----------
2420 'num' is the number of virtual YM2203s to allocate
2421 'clock' is the chip clock in Hz
2422 'rate' is sampling rate
2424 int YM2203Init(int num, int clock, int rate,
2425 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2427 int i;
2429 if (FM2203) return (-1); /* duplicate init. */
2430 cur_chip = NULL; /* hiro-shi!! */
2432 YM2203NumChips = num;
2434 /* allocate ym2203 state space */
2435 if( (FM2203 = (YM2203 *)malloc(sizeof(YM2203) * YM2203NumChips))==NULL)
2436 return (-1);
2437 /* clear */
2438 memset(FM2203,0,sizeof(YM2203) * YM2203NumChips);
2440 if( !init_tables() )
2442 if (FM2203) {
2443 free( FM2203 );
2444 FM2203 = NULL;
2446 return (-1);
2448 for ( i = 0 ; i < YM2203NumChips; i++ ) {
2449 FM2203[i].OPN.ST.index = i;
2450 FM2203[i].OPN.type = TYPE_YM2203;
2451 FM2203[i].OPN.P_CH = FM2203[i].CH;
2452 FM2203[i].OPN.ST.clock = clock;
2453 FM2203[i].OPN.ST.rate = rate;
2455 FM2203[i].OPN.ST.Timer_Handler = TimerHandler;
2456 FM2203[i].OPN.ST.IRQ_Handler = IRQHandler;
2457 YM2203ResetChip(i);
2459 #ifdef _STATE_H
2460 YM2203_save_state();
2461 #endif
2462 return(0);
2465 /* shut down emulator */
2466 void YM2203Shutdown(void)
2468 if (!FM2203) return;
2470 FMCloseTable();
2471 if (FM2203) {
2472 free(FM2203);
2473 FM2203 = NULL;
2477 /* YM2203 I/O interface */
2478 int YM2203Write(int n,int a,UINT8 v)
2480 FM_OPN *OPN = &(FM2203[n].OPN);
2482 if( !(a&1) )
2483 { /* address port */
2484 OPN->ST.address = (v &= 0xff);
2486 /* Write register to SSG emulator */
2487 if( v < 16 ) SSGWrite(n,0,v);
2489 /* prescaler select : 2d,2e,2f */
2490 if( v >= 0x2d && v <= 0x2f )
2491 OPNPrescaler_w(OPN , v , 1);
2493 else
2494 { /* data port */
2495 int addr = OPN->ST.address;
2496 #ifdef _STATE_H
2497 FM2203[n].REGS[addr] = v;
2498 #endif
2499 switch( addr & 0xf0 )
2501 case 0x00: /* 0x00-0x0f : SSG section */
2502 /* Write data to SSG emulator */
2503 SSGWrite(n,a,v);
2504 break;
2505 case 0x20: /* 0x20-0x2f : Mode section */
2506 YM2203UpdateReq(n);
2507 /* write register */
2508 OPNWriteMode(OPN,addr,v);
2509 break;
2510 default: /* 0x30-0xff : OPN section */
2511 YM2203UpdateReq(n);
2512 /* write register */
2513 OPNWriteReg(OPN,addr,v);
2515 FM_BUSY_SET(&OPN->ST,1);
2517 return OPN->ST.irq;
2520 UINT8 YM2203Read(int n,int a)
2522 YM2203 *F2203 = &(FM2203[n]);
2523 int addr = F2203->OPN.ST.address;
2524 UINT8 ret = 0;
2526 if( !(a&1) )
2527 { /* status port */
2528 ret = FM_STATUS_FLAG(&F2203->OPN.ST);
2530 else
2531 { /* data port (only SSG) */
2532 if( addr < 16 ) ret = SSGRead(n);
2534 return ret;
2537 int YM2203TimerOver(int n,int c)
2539 YM2203 *F2203 = &(FM2203[n]);
2541 if( c )
2542 { /* Timer B */
2543 TimerBOver( &(F2203->OPN.ST) );
2545 else
2546 { /* Timer A */
2547 YM2203UpdateReq(n);
2548 /* timer update */
2549 TimerAOver( &(F2203->OPN.ST) );
2550 /* CSM mode key,TL control */
2551 if( F2203->OPN.ST.mode & 0x80 )
2552 { /* CSM mode auto key on */
2553 CSMKeyControll( F2203->OPN.type, &(F2203->CH[2]) );
2556 return F2203->OPN.ST.irq;
2558 #endif /* BUILD_YM2203 */
2562 #if (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B)
2564 /* ADPCM type A channel struct */
2565 typedef struct
2567 UINT8 flag; /* port state */
2568 UINT8 flagMask; /* arrived flag mask */
2569 UINT8 now_data; /* current ROM data */
2570 UINT32 now_addr; /* current ROM address */
2571 UINT32 now_step;
2572 UINT32 step;
2573 UINT32 start; /* sample data start address*/
2574 UINT32 end; /* sample data end address */
2575 UINT8 IL; /* Instrument Level */
2576 INT32 adpcm_acc; /* accumulator */
2577 INT32 adpcm_step; /* step */
2578 INT32 adpcm_out; /* (speedup) hiro-shi!! */
2579 INT8 vol_mul; /* volume in "0.75dB" steps */
2580 UINT8 vol_shift; /* volume in "-6dB" steps */
2581 INT32 *pan; /* &out_adpcm[OPN_xxxx] */
2582 } ADPCM_CH;
2584 /* here's the virtual YM2610 */
2585 typedef struct
2587 #ifdef _STATE_H
2588 UINT8 REGS[512]; /* registers */
2589 #endif
2590 FM_OPN OPN; /* OPN state */
2591 FM_CH CH[6]; /* channel state */
2592 UINT8 addr_A1; /* address line A1 */
2594 /* ADPCM-A unit */
2595 UINT8 *pcmbuf; /* pcm rom buffer */
2596 UINT32 pcm_size; /* size of pcm rom */
2597 UINT8 adpcmTL; /* adpcmA total level */
2598 ADPCM_CH adpcm[6]; /* adpcm channels */
2599 UINT32 adpcmreg[0x30]; /* registers */
2600 UINT8 adpcm_arrivedEndAddress;
2601 YM_DELTAT deltaT; /* Delta-T ADPCM unit */
2603 UINT8 flagmask; /* YM2608 only */
2604 UINT8 irqmask; /* YM2608 only */
2605 } YM2610;
2607 /* here is the virtual YM2608 */
2608 typedef YM2610 YM2608;
2611 /**** YM2610 ADPCM defines ****/
2612 #define ADPCM_SHIFT (16) /* frequency step rate */
2613 #define ADPCMA_ADDRESS_SHIFT 8 /* adpcm A address shift */
2615 static UINT8 *pcmbufA;
2616 static UINT32 pcmsizeA;
2619 /* Algorithm and tables verified on real YM2608 and YM2610 */
2621 /* usual ADPCM table (16 * 1.1^N) */
2622 static int steps[49] =
2624 16, 17, 19, 21, 23, 25, 28,
2625 31, 34, 37, 41, 45, 50, 55,
2626 60, 66, 73, 80, 88, 97, 107,
2627 118, 130, 143, 157, 173, 190, 209,
2628 230, 253, 279, 307, 337, 371, 408,
2629 449, 494, 544, 598, 658, 724, 796,
2630 876, 963, 1060, 1166, 1282, 1411, 1552
2633 /* different from the usual ADPCM table */
2634 static int step_inc[8] = { -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16 };
2636 /* speedup purposes only */
2637 static int jedi_table[ 49*16 ];
2640 static void Init_ADPCMATable(void){
2642 int step, nib;
2644 for (step = 0; step < 49; step++)
2646 /* loop over all nibbles and compute the difference */
2647 for (nib = 0; nib < 16; nib++)
2649 int value = (2*(nib & 0x07) + 1) * steps[step] / 8;
2650 jedi_table[step*16 + nib] = (nib&0x08) ? -value : value;
2655 /* ADPCM A (Non control type) : calculate one channel output */
2656 INLINE void ADPCMA_calc_chan( YM2610 *F2610, ADPCM_CH *ch )
2658 UINT32 step;
2659 UINT8 data;
2662 ch->now_step += ch->step;
2663 if ( ch->now_step >= (1<<ADPCM_SHIFT) )
2665 step = ch->now_step >> ADPCM_SHIFT;
2666 ch->now_step &= (1<<ADPCM_SHIFT)-1;
2668 /* end check */
2669 /* 11-06-2001 JB: corrected comparison. Was > instead of == */
2670 /* YM2610 checks lower 20 bits only, the 4 MSB bits are sample bank */
2671 /* Here we use 1<<21 to compensate for nibble calculations */
2673 if ( (ch->now_addr & ((1<<21)-1)) == ((ch->end<<1) & ((1<<21)-1)) )
2675 ch->flag = 0;
2676 F2610->adpcm_arrivedEndAddress |= ch->flagMask;
2677 return;
2679 #if 0
2680 if ( ch->now_addr > (pcmsizeA<<1) ) {
2681 LOG(LOG_WAR,("YM2610: Attempting to play past adpcm rom size!\n" ));
2682 return;
2684 #endif
2685 if ( ch->now_addr&1 )
2686 data = ch->now_data & 0x0f;
2687 else
2689 ch->now_data = *(pcmbufA+(ch->now_addr>>1));
2690 data = (ch->now_data >> 4) & 0x0f;
2693 ch->now_addr++;
2695 ch->adpcm_acc += jedi_table[ch->adpcm_step + data];
2697 /* extend 12-bit signed int */
2698 if (ch->adpcm_acc & 0x800)
2699 ch->adpcm_acc |= ~0xfff;
2700 else
2701 ch->adpcm_acc &= 0xfff;
2703 ch->adpcm_step += step_inc[data & 7];
2704 Limit( ch->adpcm_step, 48*16, 0*16 );
2706 }while(--step);
2708 /* calc pcm * volume data */
2709 ch->adpcm_out = ((ch->adpcm_acc * ch->vol_mul) >> ch->vol_shift) & ~3; /* multiply, shift and mask out 2 LSB bits */
2712 /* output for work of output channels (out_adpcm[OPNxxxx])*/
2713 *(ch->pan) += ch->adpcm_out;
2716 /* ADPCM type A Write */
2717 static void FM_ADPCMAWrite(YM2610 *F2610,int r,int v)
2719 ADPCM_CH *adpcm = F2610->adpcm;
2720 UINT8 c = r&0x07;
2722 F2610->adpcmreg[r] = v&0xff; /* stock data */
2723 switch( r ){
2724 case 0x00: /* DM,--,C5,C4,C3,C2,C1,C0 */
2725 if( !(v&0x80) )
2727 /* KEY ON */
2728 for( c = 0; c < 6; c++ )
2730 if( (v>>c)&1 )
2732 /**** start adpcm ****/
2733 adpcm[c].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/3.0);
2734 adpcm[c].now_addr = adpcm[c].start<<1;
2735 adpcm[c].now_step = 0;
2736 adpcm[c].adpcm_acc = 0;
2737 adpcm[c].adpcm_step= 0;
2738 adpcm[c].adpcm_out = 0;
2739 adpcm[c].flag = 1;
2741 if(F2610->pcmbuf==NULL){ /* Check ROM Mapped */
2742 logerror("YM2608-YM2610: ADPCM-A rom not mapped\n");
2743 adpcm[c].flag = 0;
2744 } else{
2745 if(adpcm[c].end >= F2610->pcm_size){ /* Check End in Range */
2746 logerror("YM2610: ADPCM-A end out of range: $%08x\n",adpcm[c].end);
2747 /*adpcm[c].end = F2610->pcm_size-1;*/ /* JB: DO NOT uncomment this, otherwise you will break the comparison in the ADPCM_CALC_CHA() */
2749 if(adpcm[c].start >= F2610->pcm_size) /* Check Start in Range */
2751 logerror("YM2608-YM2610: ADPCM-A start out of range: $%08x\n",adpcm[c].start);
2752 adpcm[c].flag = 0;
2758 else
2760 /* KEY OFF */
2761 for( c = 0; c < 6; c++ )
2762 if( (v>>c)&1 )
2763 adpcm[c].flag = 0;
2765 break;
2766 case 0x01: /* B0-5 = TL */
2767 F2610->adpcmTL = (v & 0x3f) ^ 0x3f;
2768 for( c = 0; c < 6; c++ )
2770 int volume = F2610->adpcmTL + adpcm[c].IL;
2772 if ( volume >= 63 ) /* This is correct, 63 = quiet */
2774 adpcm[c].vol_mul = 0;
2775 adpcm[c].vol_shift = 0;
2777 else
2779 adpcm[c].vol_mul = 15 - (volume & 7); /* so called 0.75 dB */
2780 adpcm[c].vol_shift = 1 + (volume >> 3); /* Yamaha engineers used the approximation: each -6 dB is close to divide by two (shift right) */
2783 /* calc pcm * volume data */
2784 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 */
2786 break;
2787 default:
2788 c = r&0x07;
2789 if( c >= 0x06 ) return;
2790 switch( r&0x38 ){
2791 case 0x08: /* B7=L,B6=R, B4-0=IL */
2793 int volume;
2795 adpcm[c].IL = (v & 0x1f) ^ 0x1f;
2797 volume = F2610->adpcmTL + adpcm[c].IL;
2799 if ( volume >= 63 ) /* This is correct, 63 = quiet */
2801 adpcm[c].vol_mul = 0;
2802 adpcm[c].vol_shift = 0;
2804 else
2806 adpcm[c].vol_mul = 15 - (volume & 7); /* so called 0.75 dB */
2807 adpcm[c].vol_shift = 1 + (volume >> 3); /* Yamaha engineers used the approximation: each -6 dB is close to divide by two (shift right) */
2810 adpcm[c].pan = &out_adpcm[(v>>6)&0x03];
2812 /* calc pcm * volume data */
2813 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 */
2815 break;
2816 case 0x10:
2817 case 0x18:
2818 adpcm[c].start = ( (F2610->adpcmreg[0x18 + c]*0x0100 | F2610->adpcmreg[0x10 + c]) << ADPCMA_ADDRESS_SHIFT);
2819 break;
2820 case 0x20:
2821 case 0x28:
2822 adpcm[c].end = ( (F2610->adpcmreg[0x28 + c]*0x0100 | F2610->adpcmreg[0x20 + c]) << ADPCMA_ADDRESS_SHIFT);
2823 adpcm[c].end += (1<<ADPCMA_ADDRESS_SHIFT) - 1;
2824 break;
2829 #ifdef _STATE_H
2830 /* FM channel save , internal state only */
2831 static void FMsave_state_adpcma(const char *name,int num,ADPCM_CH *adpcm)
2833 int ch;
2834 char state_name[20];
2836 for(ch=0;ch<6;ch++,adpcm++)
2838 sprintf(state_name,"%s.CH%d",name,ch);
2840 state_save_register_UINT8 (state_name, num, "flag" , &adpcm->flag , 1);
2841 state_save_register_UINT8 (state_name, num, "data" , &adpcm->now_data , 1);
2842 state_save_register_UINT32(state_name, num, "addr" , &adpcm->now_addr , 1);
2843 state_save_register_UINT32(state_name, num, "step" , &adpcm->now_step , 1);
2844 state_save_register_INT32 (state_name, num, "a_acc" , &adpcm->adpcm_acc , 1);
2845 state_save_register_INT32 (state_name, num, "a_step" , &adpcm->adpcm_step, 1);
2846 state_save_register_INT32 (state_name, num, "a_out" , &adpcm->adpcm_out , 1);
2849 #endif /* _STATE_H */
2851 #endif /* (BUILD_YM2608||BUILD_YM2610||BUILD_YM2610B) */
2854 #if BUILD_YM2608
2855 /*****************************************************************************/
2856 /* YM2608 local section */
2857 /*****************************************************************************/
2858 static YM2608 *FM2608=NULL; /* array of YM2608's */
2859 static int YM2608NumChips; /* total chip */
2865 static unsigned int YM2608_ADPCM_ROM_addr[2*6] = {
2866 0x0000, 0x01bf, /* bass drum */
2867 0x01c0, 0x043f, /* snare drum */
2868 0x0440, 0x1b7f, /* top cymbal */
2869 0x1b80, 0x1cff, /* high hat */
2870 0x1d00, 0x1f7f, /* tom tom */
2871 0x1f80, 0x1fff /* rim shot */
2876 This data is derived from the chip's output - internal ROM can't be read.
2877 It was verified, using real YM2608, that this ADPCM stream produces 100% correct output signal.
2880 static unsigned char YM2608_ADPCM_ROM[0x2000] = {
2882 /* Source: 01BD.ROM */
2883 /* Length: 448 / 0x000001C0 */
2885 0x88,0x08,0x08,0x08,0x00,0x88,0x16,0x76,0x99,0xB8,0x22,0x3A,0x84,0x3C,0xB1,0x54,
2886 0x10,0xA9,0x98,0x32,0x80,0x33,0x9A,0xA7,0x4A,0xB4,0x58,0xBC,0x15,0x29,0x8A,0x97,
2887 0x9B,0x44,0xAC,0x80,0x12,0xDE,0x13,0x1B,0xC0,0x58,0xC8,0x11,0x0A,0xA2,0x1A,0xA0,
2888 0x00,0x98,0x0B,0x93,0x9E,0x92,0x0A,0x88,0xBE,0x14,0x1B,0x98,0x08,0xA1,0x4A,0xC1,
2889 0x30,0xD9,0x33,0x98,0x10,0x89,0x17,0x1A,0x82,0x29,0x37,0x0C,0x83,0x50,0x9A,0x24,
2890 0x1A,0x83,0x10,0x23,0x19,0xB3,0x72,0x8A,0x16,0x10,0x0A,0x93,0x70,0x99,0x23,0x99,
2891 0x02,0x20,0x91,0x18,0x02,0x41,0xAB,0x24,0x18,0x81,0x99,0x4A,0xE8,0x28,0x9A,0x99,
2892 0xA1,0x2F,0xA8,0x9D,0x90,0x08,0xCC,0xA3,0x1D,0xCA,0x82,0x0B,0xD8,0x08,0xB9,0x09,
2893 0xBC,0xB8,0x00,0xBE,0x90,0x1B,0xCA,0x00,0x9B,0x8A,0xA8,0x91,0x0F,0xB3,0x3D,0xB8,
2894 0x31,0x0B,0xA5,0x0A,0x11,0xA1,0x48,0x92,0x10,0x50,0x91,0x30,0x23,0x09,0x37,0x39,
2895 0xA2,0x72,0x89,0x92,0x30,0x83,0x1C,0x96,0x28,0xB9,0x24,0x8C,0xA1,0x31,0xAD,0xA9,
2896 0x13,0x9C,0xBA,0xA8,0x0B,0xBF,0xB8,0x9B,0xCA,0x88,0xDB,0xB8,0x19,0xFC,0x92,0x0A,
2897 0xBA,0x89,0xAB,0xB8,0xAB,0xD8,0x08,0xAD,0xBA,0x33,0x9D,0xAA,0x83,0x3A,0xC0,0x40,
2898 0xB9,0x15,0x39,0xA2,0x52,0x89,0x02,0x63,0x88,0x13,0x23,0x03,0x52,0x02,0x54,0x00,
2899 0x11,0x23,0x23,0x35,0x20,0x01,0x44,0x41,0x80,0x24,0x40,0xA9,0x45,0x19,0x81,0x12,
2900 0x81,0x02,0x11,0x21,0x19,0x02,0x61,0x8A,0x13,0x3A,0x10,0x12,0x23,0x8B,0x37,0x18,
2901 0x91,0x24,0x10,0x81,0x34,0x20,0x05,0x32,0x82,0x53,0x20,0x14,0x33,0x31,0x34,0x52,
2902 0x00,0x43,0x32,0x13,0x52,0x22,0x13,0x52,0x11,0x43,0x11,0x32,0x32,0x32,0x22,0x02,
2903 0x13,0x12,0x89,0x22,0x19,0x81,0x81,0x08,0xA8,0x08,0x8B,0x90,0x1B,0xBA,0x8A,0x9B,
2904 0xB9,0x89,0xCA,0xB9,0xAB,0xCA,0x9B,0xCA,0xB9,0xAB,0xDA,0x99,0xAC,0xBB,0x9B,0xAC,
2905 0xAA,0xBA,0xAC,0xAB,0x9A,0xAA,0xAA,0xBA,0xB8,0xA9,0xBA,0x99,0xA9,0x9A,0xA0,0x8A,
2906 0xA9,0x08,0x8A,0xA9,0x00,0x99,0x89,0x88,0x98,0x08,0x99,0x00,0x89,0x80,0x08,0x98,
2907 0x00,0x88,0x88,0x80,0x90,0x80,0x90,0x80,0x81,0x99,0x08,0x88,0x99,0x09,0x00,0x1A,
2908 0xA8,0x10,0x9A,0x88,0x08,0x0A,0x8A,0x89,0x99,0xA8,0x98,0xA9,0x99,0x99,0xA9,0x99,
2909 0xAA,0x8A,0xAA,0x9B,0x8A,0x9A,0xA9,0x9A,0xBA,0x99,0x9A,0xAA,0x99,0x89,0xA9,0x99,
2910 0x98,0x9A,0x98,0x88,0x09,0x89,0x09,0x08,0x08,0x09,0x18,0x18,0x00,0x12,0x00,0x11,
2911 0x11,0x11,0x12,0x12,0x21,0x21,0x22,0x22,0x22,0x22,0x22,0x22,0x32,0x31,0x32,0x31,
2912 0x32,0x32,0x21,0x31,0x21,0x32,0x21,0x12,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
2914 /* Source: 02SD.ROM */
2915 /* Length: 640 / 0x00000280 */
2917 0x0A,0xDC,0x14,0x0B,0xBA,0xBC,0x01,0x0F,0xF5,0x2F,0x87,0x19,0xC9,0x24,0x1B,0xA1,
2918 0x31,0x99,0x90,0x32,0x32,0xFE,0x83,0x48,0xA8,0xA9,0x23,0x19,0xBC,0x91,0x02,0x41,
2919 0xDE,0x81,0x28,0xA8,0x0A,0xB1,0x72,0xDA,0x23,0xBC,0x04,0x19,0xB8,0x21,0x8A,0x03,
2920 0x29,0xBA,0x14,0x21,0x0B,0xC0,0x43,0x08,0x91,0x50,0x93,0x0F,0x86,0x1A,0x91,0x18,
2921 0x21,0xCB,0x27,0x0A,0xA1,0x42,0x8C,0xA9,0x21,0x10,0x08,0xAB,0x94,0x2A,0xDA,0x02,
2922 0x8B,0x91,0x09,0x98,0xAE,0x80,0xA9,0x02,0x0A,0xE9,0x21,0xBB,0x15,0x20,0xBE,0x92,
2923 0x42,0x09,0xA9,0x11,0x34,0x08,0x12,0x0A,0x27,0x29,0xA1,0x52,0x12,0x8E,0x92,0x28,
2924 0x92,0x2B,0xD1,0x23,0xBF,0x81,0x10,0x99,0xA8,0x0A,0xC4,0x3B,0xB9,0xB0,0x00,0x62,
2925 0xCF,0x92,0x29,0x92,0x2B,0xB1,0x1C,0xB2,0x72,0xAA,0x88,0x11,0x18,0x80,0x13,0x9E,
2926 0x03,0x18,0xB0,0x60,0xA1,0x28,0x88,0x08,0x04,0x10,0x8F,0x96,0x19,0x90,0x01,0x09,
2927 0xC8,0x50,0x91,0x8A,0x01,0xAB,0x03,0x50,0xBA,0x9D,0x93,0x68,0xBA,0x80,0x22,0xCB,
2928 0x41,0xBC,0x92,0x60,0xB9,0x1A,0x95,0x4A,0xC8,0x20,0x88,0x33,0xAC,0x92,0x38,0x83,
2929 0x09,0x80,0x16,0x09,0x29,0xD0,0x54,0x8C,0xA2,0x28,0x91,0x89,0x93,0x60,0xCD,0x85,
2930 0x1B,0xA1,0x49,0x90,0x8A,0x80,0x34,0x0C,0xC9,0x14,0x19,0x98,0xA0,0x40,0xA9,0x21,
2931 0xD9,0x34,0x0A,0xA9,0x10,0x23,0xCB,0x25,0xAA,0x25,0x9B,0x13,0xCD,0x16,0x09,0xA0,
2932 0x80,0x01,0x19,0x90,0x88,0x21,0xAC,0x33,0x8B,0xD8,0x27,0x3B,0xB8,0x81,0x31,0x80,
2933 0xAF,0x97,0x0A,0x82,0x0A,0xA0,0x21,0x89,0x8A,0xA2,0x32,0x8D,0xBB,0x87,0x19,0x21,
2934 0xC9,0xBC,0x45,0x09,0x90,0x09,0xA1,0x24,0x1A,0xD0,0x10,0x08,0x11,0xA9,0x21,0xE8,
2935 0x60,0xA9,0x14,0x0C,0xD1,0x32,0xAB,0x04,0x0C,0x81,0x90,0x29,0x83,0x9B,0x01,0x8F,
2936 0x97,0x0B,0x82,0x18,0x88,0xBA,0x06,0x39,0xC8,0x23,0xBC,0x04,0x09,0x92,0x08,0x1A,
2937 0xBB,0x74,0x8C,0x81,0x18,0x81,0x9D,0x83,0x41,0xCD,0x81,0x40,0x9A,0x90,0x10,0x12,
2938 0x9C,0xA1,0x68,0xD8,0x33,0x9C,0x91,0x01,0x12,0xBE,0x02,0x09,0x12,0x99,0x9A,0x36,
2939 0x0A,0xB0,0x30,0x88,0xA3,0x2D,0x12,0xBC,0x03,0x3A,0x11,0xBD,0x08,0xC8,0x62,0x80,
2940 0x8B,0xD8,0x23,0x38,0xF9,0x12,0x08,0x99,0x91,0x21,0x99,0x85,0x2F,0xB2,0x30,0x90,
2941 0x88,0xD9,0x53,0xAC,0x82,0x19,0x91,0x20,0xCC,0x96,0x29,0xC9,0x24,0x89,0x80,0x99,
2942 0x12,0x08,0x18,0x88,0x99,0x23,0xAB,0x73,0xCB,0x33,0x9F,0x04,0x2B,0xB1,0x08,0x03,
2943 0x1B,0xC9,0x21,0x32,0xFA,0x33,0xDB,0x02,0x33,0xAE,0xB9,0x54,0x8B,0xA1,0x20,0x89,
2944 0x90,0x11,0x88,0x09,0x98,0x23,0xBE,0x37,0x8D,0x81,0x20,0xAA,0x34,0xBB,0x13,0x18,
2945 0xB9,0x40,0xB1,0x18,0x83,0x8E,0xB2,0x72,0xBC,0x82,0x30,0xA9,0x9A,0x24,0x8B,0x27,
2946 0x0E,0x91,0x20,0x90,0x08,0xB0,0x32,0xB9,0x21,0xB0,0xAC,0x45,0x9A,0xA1,0x50,0xA9,
2947 0x80,0x0A,0x26,0x9B,0x11,0xBB,0x23,0x71,0xCB,0x12,0x10,0xB8,0x40,0xA9,0xA5,0x39,
2948 0xC0,0x30,0xB2,0x20,0xAA,0xBA,0x76,0x1C,0xC1,0x48,0x98,0x80,0x18,0x81,0xAA,0x23,
2949 0x9C,0xA2,0x32,0xAC,0x9A,0x43,0x9C,0x12,0xAD,0x82,0x72,0xBC,0x00,0x82,0x39,0xD1,
2950 0x3A,0xB8,0x35,0x9B,0x10,0x40,0xF9,0x22,0x0A,0xC0,0x51,0xB9,0x82,0x18,0x98,0xA3,
2951 0x79,0xD0,0x20,0x88,0x09,0x01,0x99,0x82,0x11,0x38,0xFC,0x33,0x09,0xC8,0x40,0xA9,
2952 0x11,0x29,0xAA,0x94,0x3A,0xC2,0x4A,0xC0,0x89,0x52,0xBC,0x11,0x08,0x09,0xB8,0x71,
2953 0xA9,0x08,0xA8,0x62,0x8D,0x92,0x10,0x00,0x9E,0x94,0x38,0xBA,0x13,0x88,0x90,0x4A,
2954 0xE2,0x30,0xBA,0x02,0x00,0x19,0xD9,0x62,0xBB,0x04,0x0B,0xA3,0x68,0xB9,0x21,0x88,
2955 0x9D,0x04,0x10,0x8C,0xC8,0x62,0x99,0xAA,0x24,0x1A,0x80,0x9A,0x14,0x9B,0x26,0x8C,
2956 0x92,0x30,0xB9,0x09,0xA3,0x71,0xBB,0x10,0x19,0x82,0x39,0xDB,0x02,0x44,0x9F,0x10,
2958 /* Source: 04TOP.ROM */
2959 /* Length: 5952 / 0x00001740 */
2961 0x07,0xFF,0x7C,0x3C,0x31,0xC6,0xC4,0xBB,0x7F,0x7F,0x7B,0x82,0x8A,0x4D,0x5F,0x7C,
2962 0x3E,0x44,0xD2,0xB3,0xA0,0x19,0x1B,0x6C,0x81,0x28,0xC4,0xA1,0x1C,0x4B,0x18,0x00,
2963 0x2A,0xA2,0x0A,0x7C,0x2A,0x00,0x01,0x89,0x98,0x48,0x8A,0x3C,0x28,0x2A,0x5B,0x3E,
2964 0x3A,0x1A,0x3B,0x3D,0x4B,0x3B,0x4A,0x08,0x2A,0x1A,0x2C,0x4A,0x3B,0x82,0x99,0x3C,
2965 0x5D,0x29,0x2B,0x39,0x0B,0x23,0xAB,0x1A,0x4C,0x79,0xA3,0x01,0xC1,0x2A,0x0A,0x38,
2966 0xA7,0xB9,0x12,0x1F,0x29,0x08,0x82,0xA1,0x08,0xA9,0x42,0xAA,0x95,0xB3,0x90,0x81,
2967 0x09,0xD4,0x1A,0x80,0x1B,0x07,0xB8,0x12,0x8E,0x49,0x81,0x92,0xD3,0x90,0xA1,0x2A,
2968 0x02,0xE1,0xA3,0x99,0x02,0xB3,0x94,0xB3,0xB0,0xF4,0x98,0x93,0x90,0x13,0xE1,0x81,
2969 0x99,0x38,0x91,0xA6,0xD3,0x99,0x94,0xC1,0x83,0xB1,0x92,0x98,0x49,0xC4,0xB2,0xA4,
2970 0xA3,0xD0,0x1A,0x30,0xBA,0x59,0x02,0xD4,0xA0,0xA4,0xA2,0x8A,0x01,0x00,0xB7,0xA8,
2971 0x18,0x2A,0x2B,0x1E,0x23,0xC8,0x1A,0x00,0x39,0xA0,0x18,0x92,0x4F,0x2D,0x5A,0x10,
2972 0x89,0x81,0x2A,0x8B,0x6A,0x02,0x09,0xB3,0x8D,0x48,0x1B,0x80,0x19,0x34,0xF8,0x29,
2973 0x0A,0x7B,0x2A,0x28,0x81,0x0C,0x02,0x1E,0x29,0x09,0x12,0xC2,0x94,0xE1,0x18,0x98,
2974 0x02,0xC4,0x89,0x91,0x1A,0x20,0xA9,0x02,0x1B,0x48,0x8E,0x20,0x88,0x2D,0x08,0x59,
2975 0x1B,0x02,0xA3,0xB1,0x8A,0x1E,0x58,0x80,0xC2,0xB6,0x88,0x91,0x88,0x11,0xA1,0xA3,
2976 0xE2,0x01,0xB0,0x19,0x11,0x09,0xF4,0x88,0x09,0x88,0x19,0x89,0x12,0xF1,0x2A,0x28,
2977 0x8C,0x25,0x99,0xA4,0x98,0x39,0xA1,0x00,0xD0,0x58,0xAA,0x59,0x01,0x0C,0x00,0x2B,
2978 0x00,0x08,0x89,0x6B,0x69,0x90,0x01,0x90,0x98,0x12,0xB3,0xF3,0xA0,0x89,0x02,0x3B,
2979 0x0C,0x50,0xA9,0x4E,0x6B,0x19,0x28,0x09,0xA2,0x08,0x2F,0x20,0x88,0x92,0x8A,0x11,
2980 0xC4,0x93,0xF1,0x18,0x88,0x11,0xF2,0x80,0x92,0xA8,0x02,0xA8,0xB7,0xB3,0xA3,0xA0,
2981 0x88,0x1A,0x40,0xE2,0x91,0x19,0x88,0x18,0x91,0x83,0xC1,0xB5,0x92,0xA9,0xC6,0x90,
2982 0x01,0xC2,0x81,0x98,0x03,0xF0,0x00,0x2C,0x2A,0x92,0x2C,0x83,0x1F,0x3A,0x29,0x00,
2983 0xB8,0x70,0xAB,0x69,0x18,0x89,0x10,0x0D,0x12,0x0B,0x88,0x4A,0x3A,0x9B,0x70,0xA8,
2984 0x28,0x2F,0x2A,0x3A,0x1B,0x85,0x88,0x8B,0x6A,0x29,0x00,0x91,0x91,0x1B,0x7C,0x29,
2985 0x01,0x88,0x90,0x19,0x2B,0x2B,0x00,0x39,0xA8,0x5E,0x21,0x89,0x91,0x09,0x3A,0x6F,
2986 0x2A,0x18,0x18,0x8B,0x50,0x89,0x2B,0x19,0x49,0x88,0x29,0xF5,0x89,0x08,0x09,0x12,
2987 0xAA,0x15,0xB0,0x82,0xAC,0x38,0x00,0x3F,0x81,0x10,0xB0,0x49,0xA2,0x81,0x3A,0xC8,
2988 0x87,0x90,0xC4,0xA3,0x99,0x19,0x83,0xE1,0x84,0xE2,0xA2,0x90,0x80,0x93,0xB5,0xC4,
2989 0xB3,0xA1,0x0A,0x18,0x92,0xC4,0xA0,0x93,0x0C,0x3A,0x18,0x01,0x1E,0x20,0xB1,0x82,
2990 0x8C,0x03,0xB5,0x2E,0x82,0x19,0xB2,0x1B,0x1B,0x6B,0x4C,0x19,0x12,0x8B,0x5A,0x11,
2991 0x0C,0x3A,0x2C,0x18,0x3D,0x08,0x2A,0x5C,0x18,0x00,0x88,0x3D,0x29,0x80,0x2A,0x09,
2992 0x00,0x7A,0x0A,0x10,0x0B,0x69,0x98,0x10,0x81,0x3F,0x00,0x18,0x19,0x91,0xB7,0x9A,
2993 0x28,0x8A,0x48,0x92,0xF3,0xA2,0x88,0x98,0x87,0xA1,0x88,0x80,0x81,0x95,0xD1,0xA3,
2994 0x1B,0x1C,0x39,0x10,0xA1,0x2A,0x0B,0x7A,0x4B,0x80,0x13,0xC1,0xD1,0x2B,0x2A,0x85,
2995 0xB2,0xA2,0x93,0xB2,0xD3,0x80,0xD1,0x18,0x08,0x08,0xB7,0x98,0x81,0x3F,0x01,0x88,
2996 0x01,0xE2,0x00,0x9A,0x59,0x08,0x10,0xC3,0x99,0x84,0xA9,0xA5,0x91,0x91,0x91,0x80,
2997 0xB5,0x94,0xC0,0x01,0x98,0x09,0x84,0xB0,0x80,0x7A,0x08,0x18,0x90,0xA8,0x6A,0x1C,
2998 0x39,0x2A,0xB7,0x98,0x19,0x10,0x2A,0xA1,0x10,0xBD,0x39,0x18,0x2D,0x39,0x3F,0x10,
2999 0x3F,0x01,0x09,0x19,0x0A,0x38,0x8C,0x40,0xB3,0xB4,0x93,0xAD,0x20,0x2B,0xD4,0x81,
3000 0xC3,0xB0,0x39,0xA0,0x23,0xD8,0x04,0xB1,0x9B,0xA7,0x1A,0x92,0x08,0xA5,0x88,0x81,
3001 0xE2,0x01,0xB8,0x01,0x81,0xC1,0xC7,0x90,0x92,0x80,0xA1,0x97,0xA0,0xA2,0x82,0xB8,
3002 0x18,0x00,0x9C,0x78,0x98,0x83,0x0B,0x0B,0x32,0x7D,0x19,0x10,0xA1,0x19,0x09,0x0A,
3003 0x78,0xA8,0x10,0x1B,0x29,0x29,0x1A,0x14,0x2F,0x88,0x4A,0x1B,0x10,0x10,0xAB,0x79,
3004 0x0D,0x49,0x18,0xA0,0x02,0x1F,0x19,0x3A,0x2B,0x11,0x8A,0x88,0x79,0x8A,0x20,0x49,
3005 0x9B,0x58,0x0B,0x28,0x18,0xA9,0x3A,0x7D,0x00,0x29,0x88,0x82,0x3D,0x1A,0x38,0xBA,
3006 0x15,0x09,0xAA,0x51,0x8B,0x83,0x3C,0x8A,0x58,0x1B,0xB5,0x01,0xBB,0x50,0x19,0x99,
3007 0x24,0xCA,0x21,0x1B,0xA2,0x87,0xA8,0xB1,0x68,0xA1,0xA6,0xA2,0xA8,0x29,0x8B,0x24,
3008 0xB4,0xE2,0x92,0x8A,0x00,0x19,0x93,0xB5,0xB4,0xB1,0x81,0xB1,0x03,0x9A,0x82,0xA7,
3009 0x90,0xD6,0xA0,0x80,0x1B,0x29,0x01,0xA4,0xE1,0x18,0x0A,0x2A,0x29,0x92,0xC7,0xA8,
3010 0x81,0x19,0x89,0x30,0x10,0xE0,0x30,0xB8,0x10,0x0C,0x1A,0x79,0x1B,0xA7,0x80,0xA0,
3011 0x00,0x0B,0x28,0x18,0xB1,0x85,0x1E,0x00,0x20,0xA9,0x18,0x18,0x1C,0x13,0xBC,0x15,
3012 0x99,0x2E,0x12,0x00,0xE1,0x00,0x0B,0x3B,0x21,0x90,0x06,0xC9,0x2A,0x49,0x0A,0x18,
3013 0x20,0xD1,0x3C,0x08,0x00,0x83,0xC9,0x41,0x8E,0x18,0x08,0x02,0xA0,0x09,0xA4,0x7B,
3014 0x90,0x19,0x2A,0x10,0x2A,0xA8,0x71,0xBA,0x10,0x4A,0x0E,0x22,0xB2,0xB2,0x1B,0x8C,
3015 0x78,0x1A,0xB5,0x93,0xA9,0x1B,0x49,0x19,0x29,0xA3,0xC6,0x88,0xAA,0x32,0x0D,0x1B,
3016 0x22,0x08,0xC2,0x18,0xB9,0x79,0x3F,0x01,0x10,0xA9,0x84,0x1C,0x09,0x21,0xB0,0xA7,
3017 0x0A,0x99,0x50,0x0C,0x81,0x28,0x8B,0x48,0x2E,0x00,0x08,0x99,0x38,0x5B,0x88,0x14,
3018 0xA9,0x08,0x11,0xAA,0x72,0xC1,0xB3,0x09,0x8A,0x05,0x91,0xF2,0x81,0xA1,0x09,0x02,
3019 0xF2,0x92,0x99,0x1A,0x49,0x80,0xC5,0x90,0x90,0x18,0x09,0x12,0xA1,0xF2,0x81,0x98,
3020 0xC6,0x91,0xA0,0x11,0xA0,0x94,0xB4,0xF2,0x81,0x8B,0x03,0x80,0xD2,0x93,0xA8,0x88,
3021 0x69,0xA0,0x03,0xB8,0x88,0x32,0xBC,0x97,0x80,0xB1,0x3B,0x1A,0xA6,0x00,0xD1,0x01,
3022 0x0B,0x3B,0x30,0x9B,0x31,0x3E,0x92,0x19,0x8A,0xD3,0x5C,0x1B,0x41,0xA0,0x93,0xA2,
3023 0xAF,0x39,0x4C,0x01,0x92,0xA8,0x81,0x3C,0x0D,0x78,0x98,0x00,0x19,0x0A,0x20,0x2D,
3024 0x29,0x3C,0x1B,0x48,0x88,0x99,0x7A,0x2D,0x29,0x2A,0x82,0x80,0xA8,0x49,0x3E,0x19,
3025 0x11,0x98,0x82,0x9A,0x3B,0x28,0x2F,0x20,0x4C,0x90,0x29,0x19,0x9A,0x7A,0x29,0x28,
3026 0x98,0x88,0x33,0xCD,0x11,0x3A,0xC1,0xA4,0xA0,0xC4,0x82,0xC8,0x50,0x98,0xB2,0x21,
3027 0xC0,0xB6,0x98,0x82,0x80,0x9C,0x23,0x00,0xF8,0x30,0xA8,0x1A,0x68,0xA8,0x86,0x9A,
3028 0x01,0x2A,0x0A,0x97,0x91,0xC1,0x18,0x89,0x02,0x83,0xE0,0x01,0x8B,0x29,0x30,0xE2,
3029 0x91,0x0B,0x18,0x3B,0x1C,0x11,0x28,0xAC,0x78,0x80,0x93,0x91,0xA9,0x49,0x8B,0x87,
3030 0x90,0x99,0x3D,0x5A,0x81,0x08,0xA1,0x11,0x2F,0x1A,0x21,0x9B,0x15,0xA2,0xB0,0x11,
3031 0xC0,0x91,0x5B,0x98,0x24,0xA2,0xF2,0x92,0x8B,0x6A,0x18,0x81,0xB5,0xB1,0x88,0x4C,
3032 0x00,0x00,0xA4,0xC1,0x2B,0x1A,0x59,0x0A,0x02,0x80,0x1E,0x02,0x08,0xB3,0x80,0x9A,
3033 0x23,0xB8,0xF2,0x84,0xAB,0x01,0x48,0x90,0xA7,0x90,0x0A,0x29,0x09,0x95,0x99,0xA0,
3034 0x59,0x2B,0x00,0x97,0xB0,0x29,0x89,0x2A,0x03,0xD0,0xB7,0x1B,0x81,0x00,0xA6,0xB1,
3035 0x90,0x09,0x48,0xC0,0x11,0x00,0x8A,0x00,0x5B,0x83,0x9A,0x18,0x2F,0x3C,0x18,0x11,
3036 0xA9,0x04,0x1A,0x4F,0x01,0x98,0x81,0x09,0x09,0x4A,0x18,0xB4,0xA2,0x0B,0x59,0x90,
3037 0x3B,0x49,0xBC,0x40,0x6A,0x88,0x3A,0x08,0x3E,0x3A,0x80,0x93,0xB0,0xE1,0x5A,0x00,
3038 0xA4,0xB3,0xE3,0x90,0x0D,0x38,0x09,0x82,0xC4,0xA1,0xB1,0x4C,0x18,0x10,0x91,0xB2,
3039 0x13,0xEA,0x34,0x99,0x88,0xA6,0x89,0x92,0x91,0xC1,0x20,0xB2,0xC2,0x86,0xD2,0xB3,
3040 0x80,0xB2,0x08,0x09,0x87,0x91,0xC0,0x11,0x89,0x90,0x28,0xB9,0x79,0x19,0xA4,0x82,
3041 0xD0,0x03,0x0C,0xA3,0xA5,0xB2,0xB2,0x1B,0x29,0x13,0xF1,0xB4,0x81,0x9D,0x38,0x00,
3042 0xC4,0xA1,0x89,0x59,0x1A,0x81,0xA4,0xA9,0x1C,0x6A,0x19,0x02,0xB1,0x1A,0x4A,0x0B,
3043 0x78,0x89,0x81,0x1C,0x2A,0x29,0x4A,0xA3,0x3E,0x1C,0x49,0x1A,0x08,0x21,0xAE,0x28,
3044 0x4B,0x19,0x20,0x8C,0x10,0x3A,0xAB,0x26,0x8B,0x18,0x59,0x99,0x13,0xA2,0xAB,0x79,
3045 0x2F,0x18,0x10,0xB2,0x80,0x1B,0x4D,0x5A,0x80,0x82,0x98,0x81,0x80,0x09,0xA5,0x90,
3046 0x91,0x03,0xC2,0xE2,0x81,0xA8,0x82,0x09,0xC6,0xA3,0xB1,0x08,0x5B,0x08,0x05,0xD1,
3047 0xA2,0x89,0x2A,0x28,0x91,0xA6,0x88,0xB0,0x49,0x80,0x09,0x08,0x88,0x07,0xB8,0x05,
3048 0x99,0x81,0x88,0x18,0xE2,0x00,0xC3,0x18,0x0D,0x10,0x30,0xD0,0x93,0x8A,0x09,0x10,
3049 0x2F,0x11,0x90,0xA1,0x20,0x9B,0xB1,0x73,0xC8,0x94,0x98,0x3B,0x01,0x0C,0x30,0x19,
3050 0xF8,0x12,0x90,0xBA,0x78,0x0A,0x11,0x98,0xA0,0x79,0x8A,0x30,0x2B,0xC2,0x11,0x0D,
3051 0x09,0x7A,0x00,0x82,0xB9,0x01,0x7A,0x89,0x21,0x09,0xA1,0x0A,0x7C,0x10,0x88,0xB5,
3052 0x88,0x0A,0x2B,0x69,0x1A,0x10,0xA0,0x5B,0x19,0x1A,0x10,0x19,0x1A,0x6C,0x20,0x90,
3053 0xA5,0x98,0x1B,0x0A,0x69,0x82,0xD1,0x18,0x09,0x19,0x2A,0x93,0xD4,0x9A,0x01,0x49,
3054 0xA2,0xA2,0x82,0xD8,0x22,0xAA,0x97,0xA9,0x2D,0x38,0x2A,0xB6,0x80,0x90,0x0A,0x3C,
3055 0x82,0x94,0xB8,0x21,0x0E,0x2A,0x22,0xB8,0x00,0x4F,0x2B,0x3A,0x81,0xA1,0x29,0x2C,
3056 0x6A,0x13,0xD1,0xA2,0x98,0x28,0x0C,0x01,0xD5,0x08,0xA9,0x31,0xB3,0xB0,0xA7,0xB0,
3057 0x29,0x1B,0x87,0xA2,0xA1,0xB2,0x4A,0x89,0x11,0xC3,0xF3,0x98,0x08,0x03,0xA0,0xA3,
3058 0xC5,0x90,0xB3,0xB5,0xB4,0xB8,0x02,0x91,0x91,0xD3,0xA4,0xC1,0x1B,0x82,0x28,0xA4,
3059 0xD1,0x94,0x8A,0x28,0x08,0x03,0xE0,0x80,0xD4,0x90,0x91,0xA1,0x3B,0x3D,0x02,0xE4,
3060 0xA1,0x92,0x89,0x1A,0x4B,0x95,0xB3,0x90,0x99,0x6A,0x0A,0x30,0xA1,0x93,0xA6,0xA9,
3061 0x85,0x8B,0x82,0x10,0xB1,0xA3,0x94,0xF8,0x38,0x9A,0x30,0x1A,0x8B,0xA7,0x89,0x01,
3062 0x5B,0x19,0x18,0x11,0xF0,0x18,0x1C,0x39,0x19,0x0C,0x12,0x1C,0x2A,0x7B,0x3A,0x88,
3063 0x2B,0x18,0x2B,0x5C,0x20,0x92,0x8D,0x38,0x8A,0x3A,0x5B,0x2E,0x3A,0x2B,0x10,0x12,
3064 0xBB,0x6A,0x4D,0x18,0x10,0xB1,0x81,0x2A,0x8B,0x79,0x80,0x01,0x0A,0x09,0x5B,0x2D,
3065 0x84,0x8A,0x08,0x02,0xA2,0x91,0x82,0xE8,0x50,0x9B,0x85,0xA3,0xB0,0xA3,0x1B,0x02,
3066 0x18,0xF3,0xA2,0x88,0xAB,0x53,0xD1,0xB4,0xA3,0x09,0x09,0x18,0xD4,0x08,0xB0,0x09,
3067 0x58,0xD1,0x82,0x89,0x81,0x1A,0x18,0x05,0xB9,0xC3,0x30,0xC0,0x95,0x80,0xC3,0x89,
3068 0x89,0x13,0x88,0xF2,0x93,0x0E,0x18,0x01,0x92,0xA5,0xB8,0x2A,0x39,0xAA,0x33,0x9A,
3069 0xB1,0x11,0xF5,0xA1,0xA1,0x0A,0x50,0xB8,0x03,0xC4,0xA0,0x4E,0x29,0x10,0x88,0xC2,
3070 0x1A,0x39,0x1D,0x28,0x98,0x94,0x0E,0x10,0x2A,0x3C,0x02,0x2D,0x1B,0x4B,0x3B,0x49,
3071 0x19,0xA9,0x48,0x2F,0x29,0x10,0x89,0x02,0x0C,0x10,0x09,0xB9,0x70,0x1B,0x8A,0x50,
3072 0xA8,0x2B,0x49,0x89,0x69,0x88,0x95,0x89,0x90,0x92,0x4C,0x19,0x82,0xC1,0x01,0x80,
3073 0xA0,0x2B,0x7A,0x81,0x10,0xC2,0xB7,0x98,0x88,0x19,0x2C,0x03,0xB1,0xA4,0xA1,0x0C,
3074 0x3B,0x78,0x88,0x85,0xB1,0xA0,0x1B,0x3A,0x4A,0x08,0x94,0x81,0xF1,0x80,0x00,0x0C,
3075 0x59,0x09,0x18,0x90,0xA6,0x92,0x8C,0x1A,0x79,0x92,0xA8,0x00,0x81,0x2E,0x2A,0x13,
3076 0xA2,0xB0,0xA5,0x88,0x88,0x89,0x11,0x19,0xA0,0xF3,0x82,0xB0,0x83,0x5F,0x2A,0x01,
3077 0xA1,0x94,0xB0,0x09,0x78,0x98,0xA3,0xA6,0xA0,0x91,0x80,0x93,0x98,0xC1,0x12,0x18,
3078 0xC9,0x17,0xA0,0xA0,0x1A,0x21,0x80,0x99,0xD4,0x30,0x9D,0x00,0x10,0x2F,0x08,0x1C,
3079 0x21,0x08,0xB4,0xC3,0x2B,0xA9,0x52,0xD2,0xA3,0xD1,0x09,0x10,0x8B,0x24,0x92,0xD1,
3080 0x80,0x19,0xA0,0x2C,0x12,0x49,0xAA,0xB6,0x95,0xB8,0x08,0x3A,0x2B,0x01,0xF3,0xB3,
3081 0x0B,0x09,0x79,0x18,0xA2,0xA4,0xA0,0x18,0x0C,0x20,0x08,0xA9,0x16,0x0C,0x00,0x1B,
3082 0x08,0x2B,0x7B,0x01,0x01,0xB9,0x59,0x19,0x8B,0x45,0xA8,0x80,0x0C,0x1A,0x41,0x1E,
3083 0x00,0x28,0xA8,0x5A,0x00,0xC1,0x49,0x99,0x21,0x1D,0x08,0x85,0x99,0x95,0x89,0x90,
3084 0x11,0x90,0xD1,0x28,0xB2,0xA7,0x99,0x81,0x02,0xAC,0x13,0x81,0xB2,0xA6,0xA9,0x28,
3085 0x1C,0xB1,0x33,0xD1,0xC1,0x58,0xA8,0x14,0xB0,0xB7,0x91,0xA0,0x82,0x89,0xC2,0x28,
3086 0xA1,0xB2,0x49,0xD2,0x94,0xC8,0x12,0x80,0x99,0x85,0x08,0xD3,0x09,0xA2,0xB3,0x1E,
3087 0x08,0x21,0xB9,0x23,0xB4,0xAB,0x41,0xAC,0x87,0x09,0xA2,0xC5,0x0B,0x2A,0x5A,0x91,
3088 0x20,0x9A,0x89,0x78,0x9B,0x31,0x89,0x80,0x29,0x0A,0xB7,0x3C,0x98,0x48,0x1D,0x00,
3089 0x01,0xB0,0x20,0x2F,0x29,0x4A,0x89,0x94,0x1C,0x88,0x28,0x2B,0x10,0x88,0x9A,0x71,
3090 0x9A,0x08,0x4A,0x2F,0x18,0x2B,0x18,0x02,0xA8,0x4B,0x7A,0x99,0x48,0x80,0xA8,0x20,
3091 0x1D,0x40,0xA8,0x10,0x08,0xA8,0xC5,0x88,0xC2,0x18,0x88,0x2A,0x12,0xF3,0x82,0xD8,
3092 0x20,0x0A,0x09,0xA6,0x98,0x04,0xB9,0x11,0x18,0xC3,0xE1,0x29,0xA1,0x11,0xC1,0x03,
3093 0xE2,0x9A,0x33,0xA9,0xB5,0x98,0x92,0xA1,0x02,0xF8,0x21,0xA8,0x10,0x02,0xC1,0xB7,
3094 0x1B,0x90,0x5B,0x3C,0x83,0x93,0xE0,0x19,0x1A,0x11,0x11,0xF1,0x92,0x89,0x19,0x2C,
3095 0x2C,0x41,0x99,0x92,0x90,0x3F,0x18,0x4B,0x00,0x08,0xD2,0x01,0xB2,0xAA,0x78,0x09,
3096 0x01,0x91,0xA2,0x98,0x2F,0x3A,0x2C,0x01,0x00,0x93,0xE0,0x28,0x2C,0x2B,0x01,0x12,
3097 0xE1,0x80,0xB3,0x3D,0x3A,0x0A,0x50,0x98,0xC2,0xA0,0x11,0xAA,0x30,0x87,0x90,0xC2,
3098 0x29,0x88,0x38,0xC8,0xB5,0x90,0xBA,0x70,0x1A,0x02,0x94,0xD0,0x80,0x1A,0x82,0xA6,
3099 0xB0,0x91,0x18,0xB3,0x00,0x13,0xF1,0xA2,0xC1,0x82,0xB0,0x00,0x15,0x0B,0xD3,0x02,
3100 0xA8,0x91,0x2B,0x1F,0x49,0x88,0xA6,0x80,0x88,0x08,0x1B,0xA5,0x80,0xB9,0x06,0x0B,
3101 0x90,0x21,0x9D,0x48,0x18,0xA0,0x15,0xC9,0x82,0x2B,0x1A,0x42,0x9A,0xC4,0x39,0xBC,
3102 0x69,0x00,0xA0,0x29,0x8C,0x39,0x59,0x08,0x09,0x49,0xA9,0x6B,0x81,0x00,0x98,0xB0,
3103 0x68,0x3D,0x81,0x88,0x18,0x19,0x1D,0x12,0x80,0xB2,0x3A,0x3F,0x85,0x92,0xD0,0x00,
3104 0x0A,0x19,0x12,0xF1,0x02,0x9B,0x19,0x40,0xB9,0x11,0x02,0xF2,0x1A,0x08,0x94,0x0A,
3105 0xC2,0x83,0x0B,0xB4,0xA4,0xC0,0x32,0xD8,0x86,0x98,0x90,0x95,0x89,0xA3,0x83,0xC2,
3106 0x92,0xE1,0x92,0x82,0xD9,0x03,0x08,0xA9,0x85,0x92,0xA2,0x80,0xE0,0x30,0x8B,0xB3,
3107 0x87,0x89,0x90,0x83,0xA0,0x08,0x92,0x93,0x3E,0xAB,0x43,0x89,0xE3,0x80,0x83,0x2F,
3108 0x00,0xA3,0x80,0xC9,0x22,0x3F,0x08,0x81,0x0B,0x33,0x9A,0xA3,0x7B,0x0C,0x29,0x4A,
3109 0x1B,0x21,0xAA,0x70,0x1B,0x0D,0x48,0x1A,0x81,0x88,0xB1,0x39,0x3F,0x08,0x58,0xA0,
3110 0x81,0x1A,0x1A,0x2B,0x6D,0x11,0x0A,0x91,0x01,0x1A,0x98,0x5A,0x0C,0x03,0xB1,0x84,
3111 0xA3,0xAD,0x58,0x2A,0xA1,0x84,0xB1,0xA0,0x5C,0x2B,0x13,0xA8,0x95,0x83,0xE8,0x10,
3112 0x81,0xB0,0x00,0xC2,0x96,0xA0,0x91,0x00,0x2C,0x90,0x30,0xF2,0x80,0xA8,0x39,0x21,
3113 0xC1,0x03,0xAC,0x39,0x7C,0x29,0x91,0x1A,0x00,0x19,0x2C,0x3A,0x93,0xB0,0x29,0x8F,
3114 0x28,0x02,0x93,0xF3,0xA9,0x01,0x03,0xE0,0x08,0x09,0x1D,0x58,0xA1,0x83,0xA9,0x6B,
3115 0x2A,0x3C,0x21,0x89,0xC2,0x2C,0x4B,0x8A,0x50,0x81,0x98,0xA8,0x32,0x0C,0x8E,0x24,
3116 0x0B,0x1A,0x81,0x92,0xA1,0x4F,0x18,0x3A,0x0A,0xB4,0x18,0x2E,0x39,0x82,0x19,0xD3,
3117 0xD0,0x28,0x1B,0x11,0x98,0x07,0xAA,0x28,0x00,0x88,0xB4,0x89,0x1B,0x1F,0x22,0x00,
3118 0xB3,0xC9,0x33,0xAB,0x2B,0xB5,0x48,0x98,0x98,0xA7,0x10,0xD2,0xC1,0x23,0xCA,0x93,
3119 0xC6,0x80,0xA1,0x88,0x02,0x89,0xE2,0x09,0x38,0xBA,0x40,0x89,0x21,0xD8,0x49,0x10,
3120 0x8D,0x02,0x90,0xC3,0x9A,0x24,0x89,0x08,0x84,0xA5,0x9C,0x10,0x11,0x9C,0x88,0x30,
3121 0x3C,0xA1,0x94,0x58,0x8C,0x0B,0x69,0x29,0x9A,0x81,0x12,0x2B,0x8B,0x79,0x94,0xB0,
3122 0xC1,0x84,0xC2,0x99,0x25,0x99,0x11,0xA2,0x93,0xE4,0x99,0x80,0x0A,0x00,0x10,0xB7,
3123 0xB0,0x31,0xBA,0x3C,0x21,0xB3,0xF1,0x18,0xA0,0x2A,0x20,0xA3,0x06,0xE8,0x28,0xA1,
3124 0xB4,0x08,0x0B,0x11,0x4B,0xB7,0x90,0xA5,0x98,0x3D,0x19,0x02,0xA1,0xC4,0xB2,0x19,
3125 0x28,0xC0,0xA5,0x92,0xB1,0xA3,0x0A,0x0A,0x08,0x2B,0x70,0xC4,0xB3,0x00,0xBC,0x4B,
3126 0x39,0x12,0xE3,0xA0,0x00,0x3F,0x18,0x29,0x94,0xD1,0x19,0x09,0x00,0xA1,0x83,0x99,
3127 0x9B,0x35,0x80,0xC4,0xB1,0x6A,0x1A,0x1C,0x29,0x38,0x0E,0x19,0x5A,0x1A,0x82,0x8A,
3128 0x59,0x2A,0x2E,0x20,0x88,0xA8,0x3A,0x38,0x3D,0x00,0xB3,0x29,0xAD,0x49,0x10,0x0C,
3129 0x01,0x01,0xA3,0x8F,0x85,0x09,0x1B,0x88,0x10,0xA3,0xD2,0x90,0x3C,0x5C,0x39,0x03,
3130 0xD1,0xA0,0x00,0x2A,0x0B,0x04,0xA7,0x90,0xA0,0x11,0x90,0x99,0x83,0xB4,0xB1,0xF1,
3131 0x84,0x88,0x90,0x18,0x18,0xD3,0xD2,0xB3,0xA0,0x1A,0x21,0xA7,0xB2,0xB3,0x92,0x9A,
3132 0x22,0xB9,0x28,0x38,0xBD,0x87,0x2A,0xB1,0x13,0x0D,0x0A,0x38,0xC9,0x24,0xC0,0x19,
3133 0x23,0x0F,0x01,0x88,0xC0,0x2A,0x82,0x18,0x28,0xF0,0x18,0x2A,0x29,0x4B,0x35,0xB8,
3134 0xA3,0x9D,0x18,0x1B,0x40,0x00,0x9A,0x5C,0x3A,0x09,0x2F,0x38,0x8A,0x3B,0x3B,0x11,
3135 0x5C,0x19,0x2B,0x4A,0x08,0x0A,0x3D,0x20,0x4F,0x3A,0x19,0x2A,0x18,0x4D,0x1B,0x3A,
3136 0x11,0x0D,0x3A,0x3C,0x4B,0x93,0x81,0xAA,0x6B,0x4A,0x18,0x00,0xC3,0xC3,0x9A,0x59,
3137 0x2A,0x1B,0xA7,0xA1,0x81,0x88,0x88,0x58,0xB2,0xB1,0x2B,0x83,0xD4,0x81,0x08,0x0F,
3138 0x00,0x20,0xC2,0xE2,0x80,0x08,0x1C,0x29,0x04,0xB1,0xA2,0x01,0x1C,0x91,0x00,0x0C,
3139 0x49,0xB0,0x43,0xF2,0x99,0x39,0x3F,0x00,0x81,0x94,0xC1,0x09,0x1A,0x69,0x90,0x80,
3140 0x94,0xAA,0x20,0x2A,0x91,0xB1,0x39,0x7A,0x38,0xD1,0x10,0x8A,0x8C,0x5A,0x01,0xB5,
3141 0x98,0x80,0x2A,0x0B,0x32,0x92,0xF1,0x81,0x9A,0x23,0x8A,0xA3,0xB7,0x09,0x03,0x08,
3142 0xD0,0x94,0x9A,0x09,0x01,0x93,0xB7,0xC2,0x8C,0x3A,0x83,0x99,0x05,0xA0,0x0B,0x29,
3143 0x93,0xE5,0x80,0x89,0x38,0x90,0x8A,0xD7,0xA1,0x19,0x1B,0x48,0x98,0x92,0xC3,0xA1,
3144 0x09,0x3F,0x02,0x0C,0x22,0xC3,0xB2,0xA1,0x01,0x9F,0x4A,0x01,0xA3,0xD3,0xB0,0x28,
3145 0x3F,0x29,0x20,0xA2,0xC2,0xB1,0x08,0x5A,0x98,0x13,0xD2,0xC1,0x01,0xB2,0x80,0x3D,
3146 0x03,0xC1,0x89,0x96,0x90,0x90,0x3A,0x1A,0x9A,0x32,0xB6,0xA2,0x8E,0x4A,0x28,0x8A,
3147 0x84,0xA2,0x8A,0x2D,0x49,0x09,0x88,0x18,0x30,0x9D,0x2C,0x23,0xB1,0x0C,0x92,0x2D,
3148 0x39,0x82,0xC4,0x2E,0x10,0x1A,0x10,0xB9,0x48,0x19,0x39,0xBA,0x34,0xDA,0x2D,0x48,
3149 0x1A,0xA6,0x98,0x83,0x9A,0x1D,0x38,0x04,0xD0,0x18,0x90,0x2C,0x11,0x93,0xD3,0x9A,
3150 0x11,0x08,0x82,0xF1,0x01,0xA0,0x2A,0x93,0xD3,0xB4,0xB8,0x82,0x2F,0x11,0xA3,0xB3,
3151 0xA8,0x3B,0x09,0x23,0x96,0xC8,0x3B,0x3F,0x93,0x82,0xA1,0x90,0x3F,0x28,0x81,0xD1,
3152 0x93,0x08,0x2D,0x18,0x91,0xB3,0xB5,0x98,0x2A,0x2B,0x84,0xB1,0x5B,0x8A,0x31,0x18,
3153 0x80,0x8B,0x7E,0x39,0x2B,0x02,0xC1,0x8B,0x6C,0x49,0x09,0x10,0xA1,0x08,0x01,0x0C,
3154 0x20,0xA1,0x09,0x4F,0x18,0x00,0x01,0xA0,0x5C,0x1B,0x5B,0x10,0x92,0x90,0x2B,0x5A,
3155 0x3D,0x18,0x91,0x19,0x98,0x2D,0x39,0x89,0x2D,0x3A,0x48,0x2C,0x11,0xB5,0x9A,0x19,
3156 0x5B,0x28,0x90,0x95,0x98,0x89,0x2B,0x40,0x08,0x90,0xF3,0x0A,0x08,0xA6,0x80,0x91,
3157 0xB2,0xA0,0x02,0xF2,0xA1,0xB7,0x89,0x81,0x82,0x91,0xB1,0x21,0xAB,0x32,0xE9,0x04,
3158 0xA2,0x8D,0x12,0x91,0xA3,0xA3,0xD2,0x8B,0x39,0xD1,0x84,0xE2,0x90,0x00,0x2B,0x29,
3159 0xA3,0xD4,0xA1,0x91,0x1D,0x5A,0x08,0x19,0x11,0x99,0x08,0x18,0x49,0x0F,0x18,0x10,
3160 0x82,0xF1,0x00,0x89,0x2F,0x3A,0x01,0xB3,0xC2,0x81,0x3F,0x29,0x08,0x10,0xA1,0xA1,
3161 0x3B,0x5D,0x19,0x28,0x0B,0x38,0x82,0x91,0x19,0xBD,0x3B,0x7A,0x80,0x12,0xB3,0xE0,
3162 0x0B,0x6A,0x01,0x88,0xA4,0x08,0x0B,0x08,0x59,0x80,0x80,0x1D,0x49,0x89,0x00,0x84,
3163 0x99,0x1A,0x2B,0x32,0xE3,0xB4,0xA9,0x3A,0x99,0x31,0xE3,0xAA,0x58,0x3B,0x88,0x95,
3164 0xC0,0x18,0x4A,0x09,0x30,0xF2,0xA3,0x1C,0x1B,0x49,0x00,0xD3,0xB2,0xA0,0x18,0x11,
3165 0x92,0xD3,0xB2,0x91,0x80,0xE7,0xA1,0x91,0x98,0x19,0x22,0xC2,0xD2,0x18,0x8D,0x3B,
3166 0x10,0xA5,0x91,0x98,0x02,0x3E,0x80,0x01,0x90,0xAA,0x13,0xF1,0x02,0xD1,0x08,0x19,
3167 0x49,0xB4,0x91,0xB4,0x99,0x2A,0x0C,0x32,0xC0,0x05,0x88,0x0B,0x80,0x2C,0x81,0x10,
3168 0x0B,0x51,0xA9,0x19,0x05,0xBF,0x28,0x20,0xE1,0x90,0x80,0x28,0x19,0x08,0x26,0xB1,
3169 0xA1,0x18,0x88,0x2A,0xF0,0x12,0x8A,0xB3,0x14,0x1B,0xD4,0xD8,0x10,0x08,0x8A,0x17,
3170 0xA0,0x98,0x2B,0x3A,0x29,0x48,0xA4,0x99,0x0E,0x4A,0x12,0x8B,0x31,0x8B,0x4E,0x1A,
3171 0x11,0xB5,0x89,0x91,0x29,0x89,0xC2,0x97,0x90,0x0A,0x19,0x11,0x91,0xC1,0xD5,0x08,
3172 0x89,0x20,0x91,0xB1,0x1A,0x2D,0x18,0x29,0xD2,0x3B,0x3E,0x3A,0x2A,0x90,0x82,0x1C,
3173 0x49,0x3B,0x93,0xB6,0xC8,0x4C,0x02,0x91,0x93,0xF2,0x88,0x2D,0x28,0x81,0x82,0xC1,
3174 0x89,0x2D,0x6B,0x19,0x82,0x80,0x18,0x8B,0x39,0x39,0xC8,0x3A,0x6A,0x0A,0x22,0xD2,
3175 0x09,0x2C,0x1A,0x68,0x92,0xE2,0x89,0x2A,0x2A,0x30,0xC2,0xA3,0xB4,0x1D,0x2A,0x09,
3176 0x93,0x18,0xF2,0x89,0x28,0xB3,0x01,0x8F,0x18,0x11,0xA1,0x93,0x90,0xD1,0x7A,0x20,
3177 0xC3,0xA2,0xA8,0x88,0x1D,0x28,0xA5,0xA2,0xA2,0x0B,0x29,0x2B,0x87,0xC1,0x80,0x0A,
3178 0x19,0x01,0x12,0xF1,0x10,0x80,0x0A,0x18,0x08,0x2F,0x4A,0x02,0x89,0x1B,0x29,0x5D,
3179 0x4C,0x08,0x82,0xA1,0x0A,0x3A,0x4B,0x29,0xC6,0xC3,0x09,0x09,0x88,0x39,0x98,0x82,
3180 0xA5,0x1A,0x30,0x11,0xBD,0x3F,0x12,0x8B,0x28,0xC3,0x88,0x3F,0x2B,0x3B,0x48,0xA1,
3181 0x80,0x8A,0x4D,0x39,0x01,0x93,0xA2,0xF1,0x19,0x19,0x0A,0x02,0xB2,0x8B,0x24,0xD2,
3182 0x4B,0x12,0xC8,0x2E,0x10,0xB5,0x89,0x01,0x09,0x1C,0x2A,0x03,0xD4,0x91,0x98,0x99,
3183 0x11,0x2B,0xE4,0x00,0x00,0x01,0xE0,0xA5,0x89,0x99,0x31,0x18,0xD0,0xB7,0x98,0x18,
3184 0x0A,0x10,0x94,0xC2,0x90,0x18,0x00,0x99,0x87,0xA0,0x90,0x2A,0x3C,0x02,0xB8,0xC1,
3185 0x79,0x1A,0x20,0x08,0xA1,0xD2,0x1C,0x29,0x03,0xD1,0x29,0x99,0x2C,0x50,0xB3,0xD1,
3186 0x08,0x09,0x3C,0x10,0x04,0xB2,0x0D,0x2B,0x59,0x80,0x90,0x01,0x0F,0x3A,0x18,0x01,
3187 0xA2,0x9B,0x5B,0x3D,0x81,0x03,0xD2,0x98,0x59,0x90,0x81,0x92,0xB4,0x8B,0x1B,0x40,
3188 0xB2,0xB5,0x08,0x4B,0x01,0x09,0xD1,0x91,0x8B,0x7A,0x10,0xB3,0xC3,0x99,0x49,0x1A,
3189 0x29,0xB5,0xA2,0xAB,0x40,0x81,0x19,0xB7,0xB0,0x20,0x2B,0xD4,0x88,0xA1,0x91,0x3C,
3190 0x82,0x37,0xD3,0xB1,0x8A,0x1B,0x30,0xB3,0xF4,0xA1,0x91,0x09,0x10,0x03,0xD0,0x83,
3191 0xA9,0x8F,0x10,0x01,0x90,0x18,0x80,0x20,0x2B,0xF1,0x28,0x99,0x2A,0x41,0xF0,0x12,
3192 0xAA,0x83,0x82,0xD1,0xC1,0x08,0x89,0x59,0x09,0x83,0x87,0xB0,0x2A,0x4D,0x18,0x09,
3193 0x19,0xB3,0x4B,0x3F,0x39,0x19,0x09,0x01,0x89,0x03,0x1F,0x00,0x1A,0x0B,0x10,0x68,
3194 0xA0,0x18,0x8C,0x6A,0x09,0x08,0x97,0xA1,0x81,0x1B,0x2B,0x4C,0x03,0xB4,0xA8,0x92,
3195 0x4B,0x3C,0xA1,0x81,0x95,0xA8,0x81,0x12,0xBB,0x92,0x45,0xB9,0x93,0xF4,0x88,0x0A,
3196 0x2D,0x28,0x00,0xA3,0xA3,0x8A,0x3F,0x48,0xB1,0x92,0xB4,0xA8,0x30,0x80,0xD3,0x80,
3197 0xD1,0x19,0x3B,0xC4,0x81,0xC1,0x29,0x0D,0x20,0x13,0xC8,0xB4,0x4C,0x09,0x00,0x82,
3198 0xC2,0x3B,0x0D,0x30,0x0B,0x12,0xF0,0x1B,0x20,0x0A,0xA6,0x80,0x0A,0x4A,0x4A,0x80,
3199 0x94,0xB1,0x2E,0x3B,0x1A,0x10,0x93,0x10,0x4C,0x3D,0x08,0x82,0xC9,0x19,0x6A,0x2B,
3200 0x38,0xD1,0x08,0x19,0x2A,0x5A,0x82,0xB1,0x8D,0x29,0x78,0x09,0x82,0x0A,0x2C,0x1B,
3201 0x19,0x41,0xB8,0x8C,0x79,0x2B,0x11,0x88,0x82,0x91,0xDC,0x28,0x11,0xB0,0x11,0x18,
3202 0xC9,0x62,0xA1,0x91,0x98,0x3B,0x3A,0xB0,0xF4,0x01,0xC0,0x29,0x39,0xF8,0x95,0x91,
3203 0x88,0x88,0x91,0x03,0xA1,0xE2,0x18,0x82,0xD1,0xA2,0xD1,0x80,0x19,0x20,0x83,0xB1,
3204 0xE3,0x80,0x91,0x4D,0x1A,0x03,0xB2,0x09,0x18,0xD1,0x19,0x09,0x92,0xA6,0xA0,0xB6,
3205 0xB2,0x8B,0x38,0x10,0x42,0xD3,0xD0,0xA8,0x20,0x2C,0x10,0x01,0xB1,0xB4,0xAB,0x5B,
3206 0x79,0x80,0x10,0x1A,0xA8,0x3D,0x18,0x20,0xB3,0x8F,0x18,0x01,0x00,0x09,0xF3,0x89,
3207 0x69,0x88,0x81,0x91,0x08,0xE1,0x1A,0x08,0x11,0x81,0x1E,0x29,0xA0,0x01,0x00,0x90,
3208 0x3E,0x7B,0x18,0x82,0xC3,0xA1,0x2A,0x2C,0x5B,0x81,0xA5,0x90,0x81,0x00,0x0B,0x1A,
3209 0x1C,0x2C,0x32,0xC0,0xF3,0x80,0x2D,0x2A,0x10,0x02,0xE4,0xC1,0x89,0x4A,0x09,0x01,
3210 0x03,0xD2,0x98,0x2A,0x39,0x8A,0x89,0x26,0xB1,0xB2,0x12,0xC0,0x0A,0x5A,0x18,0x98,
3211 0xF3,0x92,0x99,0x99,0x79,0x01,0xB5,0xA1,0x80,0x80,0x90,0x83,0xA0,0xE2,0x81,0x29,
3212 0x93,0x8A,0x0A,0x6A,0x1F,0x18,0x02,0xC8,0x01,0x19,0x3B,0x4A,0x98,0x17,0xA8,0x0D,
3213 0x38,0xA1,0x91,0x10,0xA2,0x2B,0x4C,0xA6,0x81,0xBA,0x21,0x4C,0x80,0x21,0xD1,0x92,
3214 0x2C,0x08,0x30,0x9F,0x93,0x2A,0x89,0x03,0x8B,0x87,0x0A,0x0D,0x12,0x98,0xA4,0x93,
3215 0xBB,0x59,0x18,0xA1,0x32,0xE9,0x84,0x08,0x8A,0x02,0xA1,0x91,0x4B,0xB4,0x20,0x88,
3216 0xF0,0x3A,0x1A,0x88,0x87,0xB1,0x92,0x0A,0x08,0x6B,0x83,0xC3,0x91,0xC0,0x2B,0x79,
3217 0x08,0x8A,0x84,0xA0,0x89,0x40,0x1B,0xA1,0x39,0x98,0x17,0xC2,0xA2,0x12,0xCD,0x20,
3218 0x89,0x92,0x25,0xB0,0x2D,0x3A,0x8B,0x58,0x2A,0xA0,0x4C,0x08,0x30,0xAE,0x82,0x59,
3219 0x89,0x1A,0x10,0xC2,0x18,0x2C,0x40,0x1E,0x01,0xA3,0x8A,0x81,0x2C,0x29,0x29,0xA9,
3220 0x13,0x51,0xAD,0x12,0x89,0x8F,0x18,0x2C,0x39,0x00,0xC1,0x10,0x3C,0x2A,0x41,0xC8,
3221 0xA2,0x91,0x0A,0x6C,0x10,0x12,0x88,0xE8,0x30,0x91,0x81,0xD8,0x01,0x1B,0x0D,0x07,
3222 0x00,0xA8,0x92,0x0A,0x28,0xD2,0xC3,0x02,0xAA,0x94,0x81,0xB4,0xB3,0x1A,0x0B,0x13,
3223 0xF9,0x16,0xA1,0x8A,0x59,0x19,0x02,0xC1,0x91,0x8B,0x3D,0x18,0x3B,0xA4,0x94,0x80,
3224 0x99,0x88,0x1C,0x79,0x0A,0x02,0x03,0xF8,0x90,0x39,0x5B,0x19,0x02,0xC3,0x90,0xBB,
3225 0x58,0x6A,0x09,0x02,0x89,0x91,0x88,0x1A,0x69,0x8A,0x19,0x15,0xA0,0xA2,0x00,0x9A,
3226 0x6B,0x49,0x88,0xA3,0x92,0xBB,0x6B,0x3D,0x38,0x01,0x98,0x91,0x3F,0x09,0x18,0x20,
3227 0x90,0x80,0xAC,0x70,0x91,0x9B,0x51,0x09,0x88,0x99,0x14,0x8B,0x98,0x83,0x79,0xA0,
3228 0x99,0x13,0x01,0x19,0xE0,0x83,0x0B,0xB0,0x0C,0x31,0x95,0xB5,0xC2,0x8A,0x39,0x20,
3229 0x80,0x39,0xF3,0xB1,0x10,0x88,0x5E,0x18,0x94,0xA1,0x88,0xA1,0x98,0x15,0xAA,0x39,
3230 0xD4,0x84,0xC0,0xA2,0xA2,0x0C,0x81,0x86,0xB5,0xA1,0xB1,0x14,0x1B,0xB1,0x02,0x92,
3231 0xC3,0xE0,0x88,0x11,0xAA,0x69,0x18,0x81,0xA3,0xB0,0x01,0xBF,0x2A,0x31,0x93,0xF1,
3232 0x00,0x89,0x18,0x19,0x11,0xD3,0xE0,0x10,0x18,0xB1,0x18,0x24,0x9A,0x2B,0xA4,0xC0,
3233 0xB0,0x31,0x6C,0x19,0xB4,0x12,0xA8,0xEA,0x58,0x10,0x8B,0x93,0x82,0x88,0x9A,0x41,
3234 0x10,0xC3,0xEA,0x41,0xA9,0x9C,0x34,0xA1,0x2A,0x79,0xA2,0x01,0xA8,0xB3,0x28,0xCC,
3235 0x41,0x9A,0xB3,0x4B,0xB3,0x27,0x8B,0x83,0x2B,0x2F,0x08,0x28,0xB2,0x80,0x2C,0x30,
3236 0x5E,0x09,0x12,0x9B,0x09,0x22,0x5B,0x19,0x8A,0x11,0x59,0x99,0xA4,0x32,0xCD,0x18,
3237 0x08,0x10,0x85,0xB3,0xB4,0x1E,0x88,0x28,0x8A,0x11,0x09,0xC0,0x79,0x80,0x91,0x3B,
3238 0x80,0x10,0x0F,0x01,0x80,0x91,0x19,0x3D,0x92,0x28,0xA8,0x37,0x9A,0x0A,0x3A,0x8A,
3239 0x45,0xA9,0xA4,0x00,0xAA,0x09,0x3D,0x59,0x20,0xE1,0x08,0x98,0x90,0x59,0x10,0x09,
3240 0xA3,0xC3,0x93,0x99,0x2B,0x69,0x11,0xD1,0xB1,0xA4,0x91,0x3C,0x89,0x83,0xF0,0x10,
3241 0x91,0xA1,0x89,0x59,0x05,0x99,0x93,0x94,0xC8,0x08,0x0A,0x09,0x17,0xB1,0x83,0xC1,
3242 0x91,0x40,0xA2,0xC2,0x98,0xC3,0xBA,0x28,0x23,0x0F,0x80,0x50,0xB8,0x19,0x10,0x96,
3243 0x98,0x8C,0x05,0x98,0x19,0x29,0x2B,0x3B,0x0A,0xE2,0x01,0x0F,0x3C,0x38,0x08,0x09,
3244 0x81,0x4A,0x6C,0x08,0x00,0x88,0x98,0x38,0x2C,0x5A,0x1B,0x20,0x1A,0x39,0xB0,0x09,
3245 0xCB,0x5B,0x49,0x09,0x71,0x00,0xC1,0x0E,0x08,0x38,0x0C,0x02,0x10,0x0E,0x10,0x8A,
3246 0x48,0x19,0x90,0x92,0x0D,0xA3,0x98,0x3B,0x79,0x19,0x01,0x10,0xE1,0x80,0x19,0x2B,
3247 0x10,0xF2,0x02,0xAB,0x84,0x9A,0x29,0xB4,0x80,0x92,0x03,0x88,0x95,0xD0,0x03,0x90,
3248 0xA0,0xC7,0xA1,0xB0,0xA2,0x02,0x18,0xB5,0xD4,0x01,0xC0,0x08,0xA2,0x93,0xA8,0xA0,
3249 0xC3,0x20,0xF3,0x90,0x00,0xD5,0x08,0x89,0xA5,0x80,0xA0,0x81,0x82,0xC2,0x09,0xD1,
3250 0x13,0xCB,0x03,0x84,0x91,0xE1,0x1B,0x12,0x08,0xAB,0x87,0x18,0xAB,0x58,0x89,0x28,
3251 0x81,0xC9,0x33,0xA9,0x80,0x2E,0x20,0x83,0xB9,0x20,0x3B,0x9E,0x7A,0x08,0x81,0x18,
3252 0x0B,0x88,0x79,0x80,0x8B,0x00,0x12,0x0E,0x89,0x51,0x1B,0x81,0xA0,0x3A,0x01,0xAF,
3253 0x11,0x28,0xBA,0x35,0x98,0x88,0x52,0xC0,0x83,0x2F,0xA9,0x11,0x0A,0x19,0x25,0xD0,
3254 0x30,0x9C,0x08,0x21,0x98,0x81,0x2A,0xF3,0x2A,0x80,0xB6,0x2B,0x08,0x93,0xE9,0x02,
3255 0x81,0x8C,0x21,0x00,0xA6,0xA9,0x94,0x01,0x8F,0x80,0x94,0x98,0x93,0xB4,0x00,0x08,
3256 0xC0,0x14,0x98,0xB3,0xB4,0xC1,0x09,0x18,0xA7,0x00,0xA3,0xC8,0x0A,0x3C,0x19,0x96,
3257 0x83,0xC1,0x99,0x19,0x4A,0x85,0x80,0xC1,0x91,0x99,0x90,0x2A,0x17,0x95,0x99,0x88,
3258 0x12,0xAE,0x39,0x08,0x92,0x84,0xB0,0xA8,0x79,0x09,0x19,0x01,0xB2,0xA3,0x8F,0x28,
3259 0x2B,0xA2,0x40,0x82,0xA0,0x4C,0xA9,0x39,0x8D,0x81,0x70,0x88,0xA0,0x1A,0x49,0x2D,
3260 0x1A,0x26,0xA8,0x98,0x08,0x29,0x0B,0x12,0x96,0xB1,0xB2,0x3A,0x13,0x9B,0x60,0xA0,
3261 0x88,0xB2,0x34,0xEA,0x1A,0x2A,0x79,0x98,0x10,0x04,0x8C,0x1C,0x81,0x04,0x8C,0x83,
3262 0x19,0x2F,0x81,0x93,0x98,0x10,0x08,0x30,0x2A,0xFA,0x05,0x08,0x2A,0x89,0x91,0xA3,
3263 0xFA,0x11,0x11,0x00,0x8C,0x04,0x8A,0x2A,0xB5,0x10,0xA9,0xC2,0x3D,0x1B,0x32,0x04,
3264 0x0A,0x1A,0x09,0x40,0x1F,0x92,0x1D,0x2A,0x91,0x10,0x30,0x2F,0x0B,0x68,0x99,0xA2,
3265 0x92,0x88,0x78,0xA9,0x20,0x28,0xE2,0x92,0x1A,0x99,0x4B,0x19,0x22,0xA1,0xE2,0x21,
3266 0x2F,0x98,0x29,0x18,0x91,0x08,0xB0,0x79,0x1A,0x82,0x3B,0xB1,0xA7,0x8A,0xB3,0x98,
3267 0x5B,0x23,0xCA,0x42,0x83,0xF0,0x90,0x18,0x98,0x08,0xB4,0x20,0xA3,0xC0,0x43,0xD8,
3268 0x80,0x81,0xA3,0x99,0xD9,0xA7,0x19,0x90,0x10,0x05,0xB1,0x8B,0x02,0xA4,0xBD,0x23,
3269 0x93,0x8A,0x99,0x4B,0x03,0xC1,0xF8,0x38,0x09,0x2B,0x14,0xD0,0x03,0x8A,0x2A,0x39,
3270 0xB9,0x97,0x90,0xAA,0x50,0x01,0x99,0x51,0xD1,0x09,0x1A,0xB5,0x00,0x8B,0x93,0x08,
3271 0x98,0x11,0xF9,0x85,0x2B,0x08,0x96,0x89,0x90,0x2A,0x12,0x4A,0xD8,0x85,0x2B,0x0E,
3272 0x10,0x00,0x01,0xB1,0x9B,0x69,0x1A,0x90,0x40,0xB8,0x01,0x08,0x0A,0x2C,0x09,0x14,
3273 0x4B,0xE2,0x82,0x88,0xB1,0x78,0x0A,0x01,0xC2,0x93,0x19,0xCE,0x20,0x3C,0x82,0xB4,
3274 0x1B,0x20,0x8C,0x3B,0x29,0xAB,0x86,0x23,0xD8,0x81,0x9A,0x5A,0x49,0xB0,0x16,0xA0,
3275 0xB0,0x28,0x1B,0x13,0x93,0xE4,0xA2,0xA9,0x08,0x5A,0xB3,0x12,0xC1,0xE1,0x10,0x88,
3276 0x01,0x0C,0x92,0x08,0x89,0xB7,0x88,0x81,0x10,0x9A,0x17,0xA0,0xB0,0x13,0x99,0xE0,
3277 0x39,0x31,0xD2,0xB2,0x80,0x0B,0x2D,0x49,0x80,0x01,0xB0,0x06,0x09,0x0C,0x3A,0x69,
3278 0xA0,0x08,0xB2,0xA1,0x69,0x2B,0x5A,0x81,0x92,0xBA,0x21,0xB1,0x7D,0x10,0x80,0x08,
3279 0x88,0x82,0x32,0x0D,0xB0,0x1A,0x1C,0x21,0x94,0xA9,0x58,0xB9,0x5A,0x4A,0xA0,0x13,
3280 0xA9,0x80,0x7C,0x00,0x20,0x8A,0x04,0x0C,0x00,0x82,0x2A,0xB2,0xAC,0x4B,0x69,0xA0,
3281 0xA6,0x81,0x9B,0x19,0x38,0x8B,0x17,0xB2,0x81,0x2A,0xBB,0x94,0x29,0xA2,0x15,0xBA,
3282 0x97,0xA3,0xB9,0x79,0x01,0xB2,0x02,0xF1,0x90,0x0A,0x29,0x11,0x88,0xE5,0xA0,0x81,
3283 0x19,0x91,0x90,0x28,0xB3,0x14,0xD0,0xB5,0x91,0x9A,0x29,0x0B,0x07,0xA2,0xB3,0x01,
3284 0x9D,0x28,0x41,0xD0,0x91,0x90,0x82,0x1A,0xA8,0x44,0x9A,0xA9,0x21,0xE3,0xA9,0x4B,
3285 0x19,0x78,0x89,0x83,0xA3,0xB9,0x5A,0x3D,0x80,0x82,0xA2,0xA0,0x6C,0x10,0x20,0x8B,
3286 0x93,0x8B,0x0E,0x33,0xA9,0xB1,0x68,0x8A,0x31,0xAC,0x94,0xB4,0x8B,0x32,0x0B,0xB4,
3287 0x81,0x91,0x1D,0x33,0xD9,0x31,0xE1,0x8B,0x3B,0x30,0x12,0x49,0xD2,0x8E,0x29,0x18,
3288 0x8A,0x92,0x02,0xAA,0x59,0x1C,0x32,0x88,0x01,0x23,0xFB,0x83,0x29,0xDA,0x59,0x01,
3289 0x81,0x92,0xE1,0x18,0x8A,0x1D,0x30,0x93,0xF1,0x00,0x01,0x0B,0x39,0x92,0x89,0xA0,
3290 0x11,0x5B,0xE0,0x82,0x09,0x13,0xAA,0xB4,0x16,0xD8,0x91,0x2A,0x29,0x84,0x1B,0xC5,
3291 0x98,0x98,0x31,0x98,0x99,0x17,0xA9,0x20,0x92,0xC3,0x18,0x9D,0x20,0x3D,0x89,0x94,
3292 0xA2,0x1C,0x5C,0x29,0x39,0xA0,0xB3,0x00,0x0C,0x4C,0x48,0x92,0x0A,0x91,0x85,0x9A,
3293 0x01,0x82,0x1F,0x10,0x99,0x15,0xC1,0xA0,0x39,0x1A,0x1D,0x85,0xB4,0x90,0x1A,0x2A,
3294 0x4B,0x01,0xB2,0x93,0xBE,0x12,0x83,0xC9,0x18,0x09,0x20,0x78,0xF1,0x08,0x19,0x88,
3295 0x3A,0x83,0xB3,0xA9,0x93,0x7A,0x0A,0x96,0x98,0x00,0xA8,0x3A,0x30,0x92,0xF2,0x9B,
3296 0x3D,0x38,0x92,0x92,0xC3,0xB8,0x6B,0x29,0x01,0x01,0xB2,0x2F,0x09,0x19,0x18,0x01,
3297 0x3B,0x7B,0x10,0xA1,0x90,0x39,0x0F,0x38,0x0A,0xB5,0xA4,0x89,0x8B,0x6A,0x2B,0x12,
3298 0xC8,0x90,0x40,0x2A,0x9E,0x22,0x88,0x18,0x09,0x3A,0xC3,0xE8,0x09,0x59,0x08,0x12,
3299 0x94,0xD0,0x1A,0x2C,0x38,0x00,0xA1,0x83,0xE8,0x08,0x3A,0x08,0x10,0x9E,0x83,0x1D,
3300 0x92,0x19,0x2C,0x39,0x3B,0x59,0x04,0xE1,0x80,0x08,0x8D,0x21,0x81,0xB2,0xB2,0x02,
3301 0x99,0x91,0xA4,0xD6,0x98,0x99,0x03,0x80,0x98,0xA7,0x91,0x09,0xA1,0xB2,0xB3,0xE1,
3302 0x12,0x92,0xB1,0x81,0x06,0x99,0x0A,0x23,0xC4,0xB1,0xF2,0x89,0x19,0x3A,0x94,0x82,
3303 0xE0,0x89,0x38,0x0B,0xA4,0xA5,0x80,0x80,0x8C,0x34,0xB9,0xA9,0x23,0x13,0xB9,0xC1,
3304 0xC7,0x1B,0x89,0x10,0x20,0x11,0xE3,0xA8,0x4B,0x0B,0x40,0x91,0x90,0x1B,0x5F,0x2A,
3305 0x18,0x82,0x91,0x0B,0x4A,0x28,0xCA,0x40,0x80,0x5B,0x2C,0x13,0xB0,0x8A,0xA9,0x5A,
3306 0x58,0x89,0x82,0x88,0x2E,0x3B,0x31,0xA1,0x9B,0x01,0x7A,0x2C,0x01,0x91,0x93,0x3F,
3307 0x88,0x39,0x10,0xF1,0x91,0x8B,0x48,0x0A,0x12,0xE3,0xA8,0x18,0x28,0x92,0x97,0x98,
3308 0x99,0x19,0xA1,0x11,0xB6,0x88,0x3B,0x10,0xD3,0xC3,0xA1,0x2A,0x8A,0x49,0x04,0xF1,
3309 0x91,0x02,0x8A,0x89,0x04,0xF1,0x98,0x80,0x18,0x12,0xE3,0x81,0x98,0x80,0x01,0xB3,
3310 0xF2,0x99,0x12,0x2A,0xB5,0xB3,0x92,0xAA,0x19,0x50,0xB2,0xC3,0x92,0xD0,0x2B,0x68,
3311 0x93,0x99,0xC0,0x2C,0x3E,0x80,0x20,0x08,0x93,0x0D,0x2A,0x31,0x8D,0x02,0x2B,0x91,
3312 0x08,0x0A,0x03,0x2C,0x3C,0x52,0xB9,0xA0,0x12,0xBF,0x3A,0x29,0x01,0x88,0xC0,0x6A,
3313 0x3C,0x0A,0x49,0x18,0x0B,0x39,0x2B,0x69,0x0A,0x84,0x2A,0x2A,0x1C,0x2A,0xC3,0x8C,
3314 0x19,0x50,0x09,0x91,0xA7,0x8D,0x18,0x1A,0x28,0x00,0xA0,0x94,0x10,0x1F,0x20,0x90,
3315 0x8A,0x12,0xD0,0x1A,0x5A,0x81,0x04,0xBC,0x23,0x10,0xE0,0x90,0x90,0x18,0x1A,0xA6,
3316 0x12,0xB1,0xD0,0x4A,0x08,0x82,0x92,0xB6,0x9A,0x0A,0x12,0x88,0xC3,0xC5,0x8A,0x89,
3317 0x20,0xB5,0x93,0x0B,0x18,0x00,0x09,0xF2,0x88,0x2A,0x4A,0x08,0x05,0xB2,0xA9,0x3B,
3318 0x5D,0x28,0xA4,0xB1,0x00,0x19,0x19,0x7A,0xA3,0xB3,0x0A,0x90,0xA1,0xC4,0x80,0xBA,
3319 0x50,0x13,0xC1,0xC2,0x9A,0x2A,0x7B,0x28,0x84,0xC1,0x09,0x3B,0x4E,0x20,0x91,0xA1,
3320 0x18,0xAB,0x79,0x10,0xB4,0x08,0x9A,0x11,0x2B,0xF0,0x93,0xAA,0x01,0x6A,0x01,0x93,
3321 0x80,0xB8,0x2A,0x5B,0x10,0x80,0x89,0x4A,0x5B,0x92,0x15,0xB2,0xA0,0x2F,0x19,0x93,
3322 0xB8,0x95,0x80,0x1C,0x21,0xA9,0x02,0x0B,0xA0,0x5A,0x18,0x98,0x39,0x1B,0x68,0x00,
3323 0x91,0x91,0x9C,0x39,0x3E,0x18,0x84,0xB3,0x9B,0x7A,0x08,0x18,0x0A,0xB5,0x91,0x0B,
3324 0x28,0x39,0x19,0x90,0x0A,0x50,0xAC,0x11,0x01,0xAB,0x88,0x52,0x1B,0x83,0xC4,0xA2,
3325 0x9A,0xAB,0x03,0x90,0x19,0x93,0x81,0x08,0x92,0x9A,0x68,0x98,0x19,0x39,0xC1,0x92,
3326 0x8A,0x38,0x4E,0x02,0xB1,0x90,0xC3,0x18,0x2B,0x04,0xC3,0xD2,0x91,0x90,0x81,0x89,
3327 0x13,0xF1,0x88,0x93,0xA2,0x00,0x91,0xC0,0x5B,0x21,0x99,0x93,0x06,0x9A,0x1B,0x48,
3328 0x99,0xB7,0x90,0x89,0x18,0x1B,0x11,0xA4,0xB2,0x81,0x9A,0x08,0x97,0x98,0x91,0x10,
3329 0xB8,0x06,0xA2,0xA0,0x29,0x2B,0x21,0xC2,0xD1,0x10,0x1A,0x4A,0x29,0xF1,0x98,0x29,
3330 0x1B,0x31,0x10,0xA0,0xA1,0x1D,0x5A,0x29,0xB2,0x82,0xA8,0x0F,0x28,0x21,0x09,0x91,
3331 0x82,0x4D,0x10,0xA3,0xB0,0x89,0x4C,0x39,0xA0,0xA4,0xA1,0x89,0x1E,0x28,0x29,0xA3,
3332 0xC3,0x2D,0x19,0x01,0x49,0x01,0x9B,0x0C,0x21,0xC2,0xA2,0x93,0x7C,0x2A,0x10,0x90,
3334 /* Source: 08HH.ROM */
3335 /* Length: 384 / 0x00000180 */
3337 0x75,0xF2,0xAB,0x7D,0x7E,0x5C,0x3B,0x4B,0x3C,0x4D,0x4A,0x02,0xB3,0xC5,0xE7,0xE3,
3338 0x92,0xB3,0xC4,0xB3,0xC3,0x8A,0x3B,0x5D,0x5C,0x3A,0x84,0xC2,0x91,0xA4,0xE7,0xF7,
3339 0xF7,0xF4,0xA1,0x1B,0x49,0xA5,0xB1,0x1E,0x7F,0x5A,0x00,0x89,0x39,0xB7,0xA8,0x3D,
3340 0x4A,0x84,0xE7,0xF7,0xE2,0x2D,0x4C,0x3A,0x4E,0x7D,0x04,0xB0,0x2D,0x4B,0x10,0x80,
3341 0xA3,0x99,0x10,0x0E,0x59,0x93,0xC4,0xB1,0x81,0xC4,0xA2,0xB2,0x88,0x08,0x3F,0x3B,
3342 0x28,0xA6,0xC3,0xA2,0xA2,0xC5,0xC1,0x3F,0x7E,0x39,0x81,0x93,0xC2,0xA3,0xE5,0xD2,
3343 0x80,0x93,0xB8,0x6D,0x49,0x82,0xD4,0xA1,0x90,0x01,0xA0,0x09,0x04,0xE3,0xB2,0x91,
3344 0xB7,0xB3,0xA8,0x2A,0x03,0xF3,0xA1,0x92,0xC5,0xC3,0xB2,0x0B,0x30,0xB3,0x8E,0x6D,
3345 0x4A,0x01,0xB4,0xB4,0xC4,0xC3,0x99,0x3B,0x12,0xE3,0xA1,0x88,0x82,0xB4,0x9A,0x5C,
3346 0x3A,0x18,0x93,0xC3,0xB3,0xB4,0xA8,0x19,0x04,0xF3,0xA8,0x3B,0x10,0xA2,0x88,0xA5,
3347 0xB2,0x0B,0x6D,0x4B,0x10,0x91,0x89,0x3C,0x18,0x18,0xA6,0xC4,0xC3,0x98,0x19,0x2B,
3348 0x20,0x91,0xA0,0x4E,0x28,0x93,0xB3,0xC2,0x92,0xA9,0x5A,0x96,0xC4,0xC2,0x09,0x01,
3349 0xC4,0xA1,0x92,0xC4,0xA1,0x89,0x10,0xA3,0xA1,0x90,0x1C,0x5A,0x01,0xC5,0xA1,0x92,
3350 0xD4,0xB3,0xC4,0xC4,0xC3,0xA1,0x88,0x1A,0x28,0x89,0x3C,0x3A,0x3D,0x29,0x00,0x93,
3351 0xB0,0x3D,0x28,0x80,0x91,0x82,0xE3,0x99,0x2A,0x11,0xD6,0xC3,0x99,0x29,0x82,0xC4,
3352 0xC3,0xA1,0x0A,0x3B,0x3D,0x3A,0x02,0xC3,0xA2,0x99,0x3B,0x2C,0x7C,0x28,0x81,0xA3,
3353 0xB2,0xA3,0xB1,0x08,0x1A,0x3C,0x18,0x2E,0x4C,0x39,0xA5,0xB3,0xB4,0xC2,0x88,0x08,
3354 0x19,0x0A,0x49,0xB7,0xB3,0xA2,0xA1,0x92,0xA1,0x93,0xB1,0x0C,0x7D,0x39,0x93,0xB3,
3355 0xB1,0x1A,0x19,0x5D,0x28,0xA6,0xC4,0xB2,0x90,0x09,0x2A,0x18,0x1B,0x5B,0x28,0x88,
3356 0x2C,0x29,0x82,0xA0,0x18,0x91,0x2D,0x29,0x2B,0x5C,0x4C,0x3B,0x4C,0x28,0x80,0x92,
3357 0x90,0x09,0x2B,0x28,0x1D,0x6B,0x11,0xC5,0xB2,0x0B,0x39,0x09,0x4D,0x28,0x88,0x00,
3358 0x1B,0x28,0x94,0xE3,0xA0,0x1A,0x28,0xB5,0xB4,0xB3,0xB2,0x93,0xE2,0x91,0x92,0xD4,
3359 0xA0,0x1B,0x4A,0x01,0xA1,0x88,0x2D,0x5C,0x3B,0x28,0x08,0x93,0xD4,0xB2,0x91,0xB4,
3360 0xA0,0x3E,0x3B,0x4B,0x3B,0x29,0x08,0x93,0x9B,0x7B,0x3A,0x19,0x00,0x80,0x80,0xA0,
3362 /* Source: 10TOM.ROM */
3363 /* Length: 640 / 0x00000280 */
3365 0x77,0x27,0x87,0x01,0x2D,0x4F,0xC3,0xC1,0x92,0x91,0x89,0x59,0x83,0x1A,0x32,0xC2,
3366 0x95,0xB1,0x81,0x88,0x81,0x4A,0x3D,0x11,0x9E,0x0B,0x88,0x0C,0x18,0x3B,0x11,0x11,
3367 0x91,0x00,0xA0,0xE2,0x0A,0x48,0x13,0x24,0x81,0x48,0x1B,0x39,0x1C,0x83,0x84,0xA1,
3368 0xD1,0x8E,0x8A,0x0B,0xC0,0x98,0x92,0xB8,0x39,0x90,0x10,0x92,0xF0,0xB5,0x88,0x32,
3369 0x49,0x51,0x21,0x03,0x82,0x10,0x8A,0x7A,0x09,0x00,0xA2,0xCA,0x1B,0xCC,0x1C,0xB9,
3370 0x8E,0x89,0x89,0xA1,0x89,0x92,0x29,0x11,0x60,0x40,0x14,0x22,0x32,0x78,0x40,0x01,
3371 0x02,0x90,0x81,0xAB,0x0B,0x00,0xAF,0x99,0xCC,0xAB,0xDA,0xA9,0x99,0x1B,0x30,0x14,
3372 0x92,0x22,0x19,0x68,0x32,0x14,0x26,0x13,0x23,0x23,0x20,0x12,0x9A,0xA8,0xB9,0xFA,
3373 0xAA,0xCA,0xCC,0x0C,0xA8,0xAE,0x88,0xB9,0x88,0xA0,0x02,0x21,0x50,0x43,0x03,0x81,
3374 0x2A,0x11,0x34,0x63,0x24,0x33,0x22,0x38,0x8B,0xEA,0xAE,0x99,0xA0,0x90,0x82,0x00,
3375 0x89,0xBF,0x8A,0xE8,0xA9,0x90,0x01,0x12,0x13,0x12,0x08,0xA9,0xAA,0xC9,0x22,0x63,
3376 0x63,0x12,0x44,0x00,0x10,0x88,0x9C,0x98,0xA1,0x85,0x03,0x32,0x36,0x80,0x89,0xDB,
3377 0xDB,0xBB,0xB9,0xBA,0x01,0x81,0x28,0x19,0xCB,0xFA,0xBC,0x09,0x13,0x37,0x34,0x34,
3378 0x23,0x31,0x20,0x10,0x00,0x00,0x28,0x38,0x10,0x88,0xEC,0x8D,0xCB,0xBC,0xCC,0xBB,
3379 0xBB,0xC9,0x99,0x00,0x00,0x33,0x11,0x22,0x81,0x07,0x41,0x54,0x34,0x34,0x22,0x31,
3380 0x00,0x88,0x9A,0x9B,0x98,0xAB,0x8E,0x9B,0xBD,0x9C,0xBC,0xBB,0xDA,0xAA,0xA9,0x99,
3381 0x18,0x38,0x60,0x20,0x31,0x13,0x13,0x51,0x14,0x31,0x53,0x33,0x35,0x22,0x01,0x8A,
3382 0x9C,0xA9,0xCA,0xC9,0xA8,0x00,0x10,0x81,0x9C,0x9E,0xAB,0xCC,0xAB,0xBA,0x98,0x30,
3383 0x52,0x03,0x81,0x08,0x9C,0xAC,0xAC,0x18,0x11,0x03,0x51,0x61,0x41,0x31,0x31,0x02,
3384 0x01,0x20,0x24,0x43,0x44,0x40,0x30,0x10,0xBC,0xBE,0xCB,0xDB,0xAB,0xBA,0x99,0x98,
3385 0x99,0xAA,0xBD,0xAA,0xC8,0x90,0x11,0x53,0x37,0x23,0x43,0x34,0x33,0x33,0x33,0x11,
3386 0x28,0x00,0x19,0xA9,0x9A,0xCB,0xCE,0xBB,0xEB,0xBC,0xBB,0xCA,0xBA,0xA8,0x88,0x11,
3387 0x12,0x21,0x20,0x22,0x26,0x26,0x23,0x23,0x43,0x24,0x22,0x32,0x20,0x31,0x81,0x9A,
3388 0xBC,0xBC,0xCB,0xBD,0x9A,0xA9,0x90,0x98,0xBA,0xCC,0xCB,0xBC,0x8B,0x88,0x22,0x35,
3389 0x23,0x12,0x99,0x8B,0xAA,0xAA,0x89,0x82,0x93,0x31,0x42,0x23,0x23,0x21,0x32,0x11,
3390 0x20,0x13,0x13,0x24,0x24,0x24,0x22,0x11,0x8A,0x9E,0xAC,0xAC,0xAA,0xBA,0xAA,0xAB,
3391 0xBD,0xBC,0xCB,0xCB,0xA9,0xA8,0x91,0x12,0x44,0x43,0x44,0x34,0x34,0x42,0x33,0x42,
3392 0x21,0x11,0x11,0x88,0x80,0xAA,0x0B,0xAC,0xCB,0xEC,0xAC,0xBA,0xCA,0xAB,0x9A,0x99,
3393 0x80,0x91,0x09,0x08,0x10,0x22,0x44,0x43,0x44,0x33,0x43,0x22,0x13,0x21,0x22,0x20,
3394 0x09,0x88,0xB9,0xC8,0xBB,0xAB,0xAB,0xA9,0xA9,0x9B,0x9B,0x99,0x90,0x90,0x00,0x81,
3395 0x00,0x08,0x09,0x8A,0x9A,0xAA,0xA9,0xA9,0x99,0x90,0x80,0x01,0x80,0x00,0x09,0x31,
3396 0x32,0x44,0x33,0x43,0x34,0x33,0x24,0x22,0x23,0x12,0x10,0x09,0x9B,0xAB,0xCA,0xCC,
3397 0xBB,0xCB,0xDA,0xCA,0xAB,0xCA,0xAB,0xA9,0xA8,0x92,0x12,0x43,0x53,0x35,0x23,0x33,
3398 0x43,0x43,0x52,0x22,0x22,0x21,0x01,0x09,0x89,0xA9,0xBB,0xBD,0xBC,0xCB,0xDA,0xAB,
3399 0xAB,0xAB,0xAA,0xA9,0x99,0xA8,0x09,0x01,0x11,0x34,0x25,0x23,0x33,0x51,0x22,0x31,
3400 0x12,0x20,0x21,0x12,0x10,0x80,0x99,0x9A,0x99,0x99,0x88,0x08,0x00,0x88,0xA9,0x99,
3401 0x99,0x80,0x80,0x10,0x01,0x00,0x9A,0xAA,0xBB,0xBA,0xBA,0xA9,0x99,0x99,0x89,0x99,
3402 0x99,0x00,0x01,0x33,0x35,0x24,0x23,0x34,0x23,0x33,0x34,0x33,0x43,0x32,0x21,0x88,
3403 0xAB,0xBD,0xBB,0xDB,0xAB,0xBA,0xBB,0xDA,0xBB,0xCB,0xBB,0xBC,0xA8,0x90,0x01,0x12,
3404 0x23,0x43,0x53,0x34,0x34,0x39,0x80,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,
3406 /* Source: 20RIM.ROM */
3407 /* Length: 128 / 0x00000080 */
3409 0x0F,0xFF,0x73,0x8E,0x71,0xCD,0x00,0x49,0x10,0x90,0x21,0x49,0xA0,0xDB,0x02,0x3A,
3410 0xE3,0x0A,0x50,0x98,0xC0,0x59,0xA2,0x99,0x09,0x22,0xA2,0x80,0x10,0xA8,0x5B,0xD2,
3411 0x88,0x21,0x09,0x96,0xA8,0x10,0x0A,0xE0,0x08,0x48,0x19,0xAB,0x52,0xA8,0x92,0x0C,
3412 0x03,0x19,0xE2,0x0A,0x12,0xC2,0x81,0x1E,0x01,0xD0,0x48,0x88,0x98,0x01,0x49,0x91,
3413 0xAA,0x2C,0x25,0x89,0x88,0xB5,0x81,0xA2,0x9A,0x12,0x9E,0x38,0x3B,0x81,0x9B,0x59,
3414 0x01,0x93,0xCA,0x4A,0x21,0xA0,0x3D,0x0A,0x39,0x3D,0x12,0xA8,0x3F,0x18,0x01,0x92,
3415 0x1C,0x00,0xB2,0x48,0xB9,0x94,0xA3,0x19,0x4F,0x19,0xB2,0x32,0x90,0xBA,0x01,0xE6,
3416 0x91,0x80,0xC1,0xA4,0x2A,0x08,0xA1,0xB1,0x25,0xD2,0x88,0x99,0x21,0x80,0x88,0x80,
3421 /* flag enable control 0x110 */
3422 INLINE void YM2608IRQFlagWrite(FM_OPN *OPN, int n, int v)
3424 YM2608 *F2608 = &(FM2608[n]);
3426 if( v & 0x80 )
3427 { /* Reset IRQ flag */
3428 FM_STATUS_RESET(&OPN->ST, 0xf7); /* don't touch BUFRDY flag otherwise we'd have to call ymdeltat module to set the flag back */
3430 else
3431 { /* Set status flag mask */
3432 F2608->flagmask = (~(v&0x1f));
3433 FM_IRQMASK_SET(&OPN->ST, (F2608->irqmask & F2608->flagmask) );
3437 /* compatible mode & IRQ enable control 0x29 */
3438 INLINE void YM2608IRQMaskWrite(FM_OPN *OPN, int n, int v)
3440 YM2608 *F2608 = &(FM2608[n]);
3441 /* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
3443 /* extend 3ch. enable/disable */
3444 if(v&0x80)
3445 OPN->type |= TYPE_6CH; /* OPNA mode - 6 FM channels */
3446 else
3447 OPN->type &= ~TYPE_6CH; /* OPN mode - 3 FM channels */
3449 /* IRQ MASK store and set */
3450 F2608->irqmask = v&0x1f;
3451 FM_IRQMASK_SET(&OPN->ST, (F2608->irqmask & F2608->flagmask) );
3454 /* Generate samples for one of the YM2608s */
3455 void YM2608UpdateOne(int num, INT16 **buffer, int length)
3457 YM2608 *F2608 = &(FM2608[num]);
3458 FM_OPN *OPN = &(FM2608[num].OPN);
3459 YM_DELTAT *DELTAT = &(F2608[num].deltaT);
3460 int i,j;
3461 FMSAMPLE *bufL,*bufR;
3463 /* set bufer */
3464 bufL = buffer[0];
3465 bufR = buffer[1];
3467 if( (void *)F2608 != cur_chip ){
3468 cur_chip = (void *)F2608;
3470 State = &OPN->ST;
3471 cch[0] = &F2608->CH[0];
3472 cch[1] = &F2608->CH[1];
3473 cch[2] = &F2608->CH[2];
3474 cch[3] = &F2608->CH[3];
3475 cch[4] = &F2608->CH[4];
3476 cch[5] = &F2608->CH[5];
3477 /* setup adpcm rom address */
3478 pcmbufA = F2608->pcmbuf;
3479 pcmsizeA = F2608->pcm_size;
3483 /* refresh PG and EG */
3484 refresh_fc_eg_chan( OPN, cch[0] );
3485 refresh_fc_eg_chan( OPN, cch[1] );
3486 if( (State->mode & 0xc0) )
3488 /* 3SLOT MODE */
3489 if( cch[2]->SLOT[SLOT1].Incr==-1)
3491 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
3492 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
3493 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
3494 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
3496 }else refresh_fc_eg_chan( OPN, cch[2] );
3497 refresh_fc_eg_chan( OPN, cch[3] );
3498 refresh_fc_eg_chan( OPN, cch[4] );
3499 refresh_fc_eg_chan( OPN, cch[5] );
3502 /* buffering */
3503 for(i=0; i < length ; i++)
3506 advance_lfo(OPN);
3508 /* clear output acc. */
3509 out_adpcm[OUTD_LEFT] = out_adpcm[OUTD_RIGHT]= out_adpcm[OUTD_CENTER] = 0;
3510 out_delta[OUTD_LEFT] = out_delta[OUTD_RIGHT]= out_delta[OUTD_CENTER] = 0;
3511 /* clear outputs */
3512 out_fm[0] = 0;
3513 out_fm[1] = 0;
3514 out_fm[2] = 0;
3515 out_fm[3] = 0;
3516 out_fm[4] = 0;
3517 out_fm[5] = 0;
3519 /* advance envelope generator */
3520 OPN->eg_timer += OPN->eg_timer_add;
3521 while (OPN->eg_timer >= OPN->eg_timer_overflow)
3523 OPN->eg_timer -= OPN->eg_timer_overflow;
3524 OPN->eg_cnt++;
3526 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
3527 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
3528 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
3529 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
3530 advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]);
3531 advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]);
3534 /* calculate FM */
3535 chan_calc(OPN, cch[0], 0 );
3536 chan_calc(OPN, cch[1], 1 );
3537 chan_calc(OPN, cch[2], 2 );
3538 chan_calc(OPN, cch[3], 3 );
3539 chan_calc(OPN, cch[4], 4 );
3540 chan_calc(OPN, cch[5], 5 );
3542 /* deltaT ADPCM */
3543 if( DELTAT->portstate&0x80 )
3544 YM_DELTAT_ADPCM_CALC(DELTAT);
3546 /* ADPCMA */
3547 for( j = 0; j < 6; j++ )
3549 if( F2608->adpcm[j].flag )
3550 ADPCMA_calc_chan( F2608, &F2608->adpcm[j]);
3553 /* buffering */
3555 int lt,rt;
3557 lt = out_adpcm[OUTD_LEFT] + out_adpcm[OUTD_CENTER];
3558 rt = out_adpcm[OUTD_RIGHT] + out_adpcm[OUTD_CENTER];
3559 lt += (out_delta[OUTD_LEFT] + out_delta[OUTD_CENTER])>>9;
3560 rt += (out_delta[OUTD_RIGHT] + out_delta[OUTD_CENTER])>>9;
3561 lt += ((out_fm[0]>>1) & OPN->pan[0]); /* shift right verified on real YM2608 */
3562 rt += ((out_fm[0]>>1) & OPN->pan[1]);
3563 lt += ((out_fm[1]>>1) & OPN->pan[2]);
3564 rt += ((out_fm[1]>>1) & OPN->pan[3]);
3565 lt += ((out_fm[2]>>1) & OPN->pan[4]);
3566 rt += ((out_fm[2]>>1) & OPN->pan[5]);
3567 lt += ((out_fm[3]>>1) & OPN->pan[6]);
3568 rt += ((out_fm[3]>>1) & OPN->pan[7]);
3569 lt += ((out_fm[4]>>1) & OPN->pan[8]);
3570 rt += ((out_fm[4]>>1) & OPN->pan[9]);
3571 lt += ((out_fm[5]>>1) & OPN->pan[10]);
3572 rt += ((out_fm[5]>>1) & OPN->pan[11]);
3574 lt >>= FINAL_SH;
3575 rt >>= FINAL_SH;
3577 Limit( lt, MAXOUT, MINOUT );
3578 Limit( rt, MAXOUT, MINOUT );
3579 /* buffering */
3580 bufL[i] = lt;
3581 bufR[i] = rt;
3583 #ifdef SAVE_SAMPLE
3584 SAVE_ALL_CHANNELS
3585 #endif
3589 /* timer A control */
3590 INTERNAL_TIMER_A( State , cch[2] )
3592 INTERNAL_TIMER_B(State,length)
3595 /* check IRQ for DELTA-T EOS */
3596 FM_STATUS_SET(State, 0);
3599 #ifdef _STATE_H
3600 static void YM2608_postload(void)
3602 int num , r;
3604 for(num=0;num<YM2608NumChips;num++)
3606 YM2608 *F2608 = &(FM2608[num]);
3607 /* prescaler */
3608 OPNPrescaler_w(&F2608->OPN,1,2);
3609 F2608->deltaT.freqbase = F2608->OPN.ST.freqbase;
3610 /* IRQ mask / mode */
3611 YM2608IRQMaskWrite(&F2608->OPN, num, F2608->REGS[0x29]);
3612 /* SSG registers */
3613 for(r=0;r<16;r++)
3615 SSGWrite(num,0,r);
3616 SSGWrite(num,1,F2608->REGS[r]);
3619 /* OPN registers */
3620 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
3621 for(r=0x30;r<0x9e;r++)
3622 if((r&3) != 3)
3624 OPNWriteReg(&F2608->OPN,r,F2608->REGS[r]);
3625 OPNWriteReg(&F2608->OPN,r|0x100,F2608->REGS[r|0x100]);
3627 /* FB / CONNECT , L / R / AMS / PMS */
3628 for(r=0xb0;r<0xb6;r++)
3629 if((r&3) != 3)
3631 OPNWriteReg(&F2608->OPN,r,F2608->REGS[r]);
3632 OPNWriteReg(&F2608->OPN,r|0x100,F2608->REGS[r|0x100]);
3634 /* FM channels */
3635 /*FM_channel_postload(F2608->CH,6);*/
3636 /* rhythm(ADPCMA) */
3637 FM_ADPCMAWrite(F2608,1,F2608->REGS[0x111]);
3638 for( r=0x08 ; r<0x0c ; r++)
3639 FM_ADPCMAWrite(F2608,r,F2608->REGS[r+0x110]);
3640 /* Delta-T ADPCM unit */
3641 YM_DELTAT_postload(&F2608->deltaT , &F2608->REGS[0x100] );
3643 cur_chip = NULL;
3646 static void YM2608_save_state(void)
3648 int num;
3649 const char statename[] = "YM2608";
3651 for(num=0;num<YM2608NumChips;num++)
3653 YM2608 *F2608 = &(FM2608[num]);
3655 state_save_register_UINT8 (statename, num, "regs" , F2608->REGS , 512);
3656 FMsave_state_st(statename,num,&FM2608[num].OPN.ST);
3657 FMsave_state_channel(statename,num,FM2608[num].CH,6);
3658 /* 3slots */
3659 state_save_register_UINT32(statename, num, "slot3fc" , F2608->OPN.SL3.fc , 3);
3660 state_save_register_UINT8 (statename, num, "slot3fh" , &F2608->OPN.SL3.fn_h, 1);
3661 state_save_register_UINT8 (statename, num, "slot3kc" , F2608->OPN.SL3.kcode, 3);
3662 /* address register1 */
3663 state_save_register_UINT8 (statename, num, "addr_A1" , &F2608->addr_A1 ,1);
3664 /* rythm(ADPCMA) */
3665 FMsave_state_adpcma(statename,num,F2608->adpcm);
3666 /* Delta-T ADPCM unit */
3667 YM_DELTAT_savestate(statename,num,&FM2608[num].deltaT);
3669 state_save_register_func_postload(YM2608_postload);
3671 #endif /* _STATE_H */
3673 static void YM2608_deltat_status_set(UINT8 which, UINT8 changebits)
3675 FM_STATUS_SET(&(FM2608[which].OPN.ST), changebits);
3677 static void YM2608_deltat_status_reset(UINT8 which, UINT8 changebits)
3679 FM_STATUS_RESET(&(FM2608[which].OPN.ST), changebits);
3681 /* YM2608(OPNA) */
3682 int YM2608Init(int num, int clock, int rate,
3683 void **pcmrom,int *pcmsize,
3684 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
3686 int i;
3688 if (FM2608) return (-1); /* duplicate init. */
3689 cur_chip = NULL;
3691 YM2608NumChips = num;
3693 /* allocate extend state space */
3694 if( (FM2608 = (YM2608 *)malloc(sizeof(YM2608) * YM2608NumChips))==NULL)
3695 return (-1);
3696 /* clear */
3697 memset(FM2608,0,sizeof(YM2608) * YM2608NumChips);
3698 /* allocate total level table (128kb space) */
3699 if( !init_tables() )
3701 if (FM2608) {
3702 free( FM2608 );
3703 FM2608 = NULL;
3705 return (-1);
3708 for ( i = 0 ; i < YM2608NumChips; i++ ) {
3709 FM2608[i].OPN.ST.index = i;
3710 FM2608[i].OPN.type = TYPE_YM2608;
3711 FM2608[i].OPN.P_CH = FM2608[i].CH;
3712 FM2608[i].OPN.ST.clock = clock;
3713 FM2608[i].OPN.ST.rate = rate;
3715 /* External handlers */
3716 FM2608[i].OPN.ST.Timer_Handler = TimerHandler;
3717 FM2608[i].OPN.ST.IRQ_Handler = IRQHandler;
3719 /* DELTA-T */
3720 FM2608[i].deltaT.memory = (UINT8 *)(pcmrom[i]);
3721 FM2608[i].deltaT.memory_size = pcmsize[i];
3723 /*FM2608[i].deltaT.write_time = 20.0 / clock;*/ /* a single byte write takes 20 cycles of main clock */
3724 /*FM2608[i].deltaT.read_time = 18.0 / clock;*/ /* a single byte read takes 18 cycles of main clock */
3726 FM2608[i].deltaT.status_set_handler = YM2608_deltat_status_set;
3727 FM2608[i].deltaT.status_reset_handler = YM2608_deltat_status_reset;
3728 FM2608[i].deltaT.status_change_which_chip = i;
3729 FM2608[i].deltaT.status_change_EOS_bit = 0x04; /* status flag: set bit2 on End Of Sample */
3730 FM2608[i].deltaT.status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY */
3731 FM2608[i].deltaT.status_change_ZERO_bit = 0x10; /* status flag: set bit4 if silence continues for more than 290 miliseconds while recording the ADPCM */
3733 /* ADPCM Rhythm */
3734 FM2608[i].pcmbuf = YM2608_ADPCM_ROM;
3735 FM2608[i].pcm_size = 0x2000;
3737 YM2608ResetChip(i);
3740 Init_ADPCMATable();
3742 #ifdef _STATE_H
3743 YM2608_save_state();
3744 #endif
3745 return 0;
3748 /* shut down emulator */
3749 void YM2608Shutdown()
3751 if (!FM2608) return;
3753 FMCloseTable();
3754 if (FM2608) {
3755 free(FM2608);
3756 FM2608 = NULL;
3760 /* reset one of chips */
3761 void YM2608ResetChip(int num)
3763 int i;
3764 YM2608 *F2608 = &(FM2608[num]);
3765 FM_OPN *OPN = &(FM2608[num].OPN);
3766 YM_DELTAT *DELTAT = &(F2608[num].deltaT);
3768 /* Reset Prescaler */
3769 OPNPrescaler_w(OPN , 0 , 2);
3770 F2608->deltaT.freqbase = OPN->ST.freqbase;
3771 /* reset SSG section */
3772 SSGReset(OPN->ST.index);
3774 /* status clear */
3775 FM_BUSY_CLEAR(&OPN->ST);
3777 /* register 0x29 - default value after reset is:
3778 enable only 3 FM channels and enable all the status flags */
3779 YM2608IRQMaskWrite(OPN, num, 0x1f ); /* default value for D4-D0 is 1 */
3781 /* register 0x10, A1=1 - default value is 1 for D4, D3, D2, 0 for the rest */
3782 YM2608IRQFlagWrite(OPN, num, 0x1c ); /* default: enable timer A and B, disable EOS, BRDY and ZERO */
3784 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
3786 OPN->eg_timer = 0;
3787 OPN->eg_cnt = 0;
3789 FM_STATUS_RESET(&OPN->ST, 0xff);
3791 reset_channels( &OPN->ST , F2608->CH , 6 );
3792 /* reset OPerator paramater */
3793 for(i = 0xb6 ; i >= 0xb4 ; i-- )
3795 OPNWriteReg(OPN,i ,0xc0);
3796 OPNWriteReg(OPN,i|0x100,0xc0);
3798 for(i = 0xb2 ; i >= 0x30 ; i-- )
3800 OPNWriteReg(OPN,i ,0);
3801 OPNWriteReg(OPN,i|0x100,0);
3803 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
3805 /* ADPCM - percussion sounds */
3806 for( i = 0; i < 6; i++ )
3808 if (i<=3) /* channels 0,1,2,3 */
3809 F2608->adpcm[i].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2608->OPN.ST.freqbase)/3.0);
3810 else /* channels 4 and 5 work with slower clock */
3811 F2608->adpcm[i].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2608->OPN.ST.freqbase)/6.0);
3813 F2608->adpcm[i].start = YM2608_ADPCM_ROM_addr[i*2];
3814 F2608->adpcm[i].end = YM2608_ADPCM_ROM_addr[i*2+1];
3816 F2608->adpcm[i].now_addr = 0;
3817 F2608->adpcm[i].now_step = 0;
3818 /* F2608->adpcm[i].delta = 21866; */
3819 F2608->adpcm[i].vol_mul = 0;
3820 F2608->adpcm[i].pan = &out_adpcm[OUTD_CENTER]; /* default center */
3821 F2608->adpcm[i].flagMask = 0;
3822 F2608->adpcm[i].flag = 0;
3823 F2608->adpcm[i].adpcm_acc = 0;
3824 F2608->adpcm[i].adpcm_step= 0;
3825 F2608->adpcm[i].adpcm_out = 0;
3827 F2608->adpcmTL = 0x3f;
3829 F2608->adpcm_arrivedEndAddress = 0; /* not used */
3831 /* DELTA-T unit */
3832 DELTAT->freqbase = OPN->ST.freqbase;
3833 DELTAT->output_pointer = out_delta;
3834 DELTAT->portshift = 5; /* always 5bits shift */ /* ASG */
3835 DELTAT->output_range = 1<<23;
3836 YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER,YM_DELTAT_EMULATION_MODE_NORMAL);
3839 /* YM2608 write */
3840 /* n = number */
3841 /* a = address */
3842 /* v = value */
3843 int YM2608Write(int n, int a,UINT8 v)
3845 YM2608 *F2608 = &(FM2608[n]);
3846 FM_OPN *OPN = &(FM2608[n].OPN);
3847 int addr;
3849 v &= 0xff; /*adjust to 8 bit bus */
3852 switch(a&3)
3854 case 0: /* address port 0 */
3855 OPN->ST.address = v;
3856 F2608->addr_A1 = 0;
3858 /* Write register to SSG emulator */
3859 if( v < 16 ) SSGWrite(n,0,v);
3860 /* prescaler selecter : 2d,2e,2f */
3861 if( v >= 0x2d && v <= 0x2f )
3863 OPNPrescaler_w(OPN , v , 2);
3864 F2608->deltaT.freqbase = OPN->ST.freqbase;
3866 break;
3868 case 1: /* data port 0 */
3869 if (F2608->addr_A1 != 0)
3870 break; /* verified on real YM2608 */
3872 addr = OPN->ST.address;
3873 #ifdef _STATE_H
3874 F2608->REGS[addr] = v;
3875 #endif
3876 switch(addr & 0xf0)
3878 case 0x00: /* SSG section */
3879 /* Write data to SSG emulator */
3880 SSGWrite(n,a,v);
3881 break;
3882 case 0x10: /* 0x10-0x1f : Rhythm section */
3883 YM2608UpdateReq(n);
3884 FM_ADPCMAWrite(F2608,addr-0x10,v);
3885 break;
3886 case 0x20: /* Mode Register */
3887 switch(addr)
3889 case 0x29: /* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
3890 YM2608IRQMaskWrite(OPN, n, v);
3891 break;
3892 default:
3893 YM2608UpdateReq(n);
3894 OPNWriteMode(OPN,addr,v);
3896 break;
3897 default: /* OPN section */
3898 YM2608UpdateReq(n);
3899 OPNWriteReg(OPN,addr,v);
3901 break;
3903 case 2: /* address port 1 */
3904 OPN->ST.address = v;
3905 F2608->addr_A1 = 1;
3906 break;
3908 case 3: /* data port 1 */
3909 if (F2608->addr_A1 != 1)
3910 break; /* verified on real YM2608 */
3912 addr = OPN->ST.address;
3913 #ifdef _STATE_H
3914 F2608->REGS[addr | 0x100] = v;
3915 #endif
3916 YM2608UpdateReq(n);
3917 switch( addr & 0xf0 )
3919 case 0x00: /* DELTAT PORT */
3920 switch( addr )
3922 case 0x0e: /* DAC data */
3923 logerror("YM2608: write to DAC data (unimplemented) value=%02x\n",v);
3924 break;
3925 default:
3926 /* 0x00-0x0d */
3927 YM_DELTAT_ADPCM_Write(&F2608->deltaT,addr,v);
3929 break;
3930 case 0x10: /* IRQ Flag control */
3931 if( addr == 0x10 )
3933 YM2608IRQFlagWrite(OPN, n, v);
3935 break;
3936 default:
3937 OPNWriteReg(OPN,addr | 0x100,v);
3940 return OPN->ST.irq;
3943 UINT8 YM2608Read(int n,int a)
3945 YM2608 *F2608 = &(FM2608[n]);
3946 int addr = F2608->OPN.ST.address;
3947 UINT8 ret = 0;
3949 switch( a&3 ){
3950 case 0: /* status 0 : YM2203 compatible */
3951 /* BUSY:x:x:x:x:x:FLAGB:FLAGA */
3952 ret = FM_STATUS_FLAG(&F2608->OPN.ST) & 0x83;
3953 break;
3955 case 1: /* status 0, ID */
3956 if( addr < 16 ) ret = SSGRead(n);
3957 else if(addr == 0xff) ret = 0x01; /* ID code */
3958 break;
3960 case 2: /* status 1 : status 0 + ADPCM status */
3961 /* BUSY : x : PCMBUSY : ZERO : BRDY : EOS : FLAGB : FLAGA */
3962 ret = (FM_STATUS_FLAG(&F2608->OPN.ST) & (F2608->flagmask|0x80)) | ((F2608->deltaT.PCM_BSY & 1)<<5) ;
3963 break;
3965 case 3:
3966 if(addr == 0x08)
3968 ret = YM_DELTAT_ADPCM_Read(&F2608->deltaT);
3970 else
3972 if(addr == 0x0f)
3974 logerror("YM2608 A/D convertion is accessed but not implemented !\n");
3975 ret = 0x80; /* 2's complement PCM data - result from A/D convertion */
3978 break;
3980 return ret;
3983 int YM2608TimerOver(int n,int c)
3985 YM2608 *F2608 = &(FM2608[n]);
3987 switch(c)
3989 #if 0
3990 case 2:
3991 { /* BUFRDY flag */
3992 YM_DELTAT_BRDY_callback( &F2608->deltaT );
3994 break;
3995 #endif
3996 case 1:
3997 { /* Timer B */
3998 TimerBOver( &(F2608->OPN.ST) );
4000 break;
4001 case 0:
4002 { /* Timer A */
4003 YM2608UpdateReq(n);
4004 /* timer update */
4005 TimerAOver( &(F2608->OPN.ST) );
4006 /* CSM mode key,TL controll */
4007 if( F2608->OPN.ST.mode & 0x80 )
4008 { /* CSM mode total level latch and auto key on */
4009 CSMKeyControll( F2608->OPN.type, &(F2608->CH[2]) );
4012 break;
4013 default:
4014 break;
4017 return FM2608->OPN.ST.irq;
4020 #endif /* BUILD_YM2608 */
4024 #if (BUILD_YM2610||BUILD_YM2610B)
4025 /* YM2610(OPNB) */
4026 static YM2610 *FM2610=NULL; /* array of YM2610's */
4027 static int YM2610NumChips;
4029 /* Generate samples for one of the YM2610s */
4030 void YM2610UpdateOne(int num, INT16 **buffer, int length)
4032 YM2610 *F2610 = &(FM2610[num]);
4033 FM_OPN *OPN = &(FM2610[num].OPN);
4034 YM_DELTAT *DELTAT = &(F2610[num].deltaT);
4035 int i,j;
4036 FMSAMPLE *bufL,*bufR;
4038 /* buffer setup */
4039 bufL = buffer[0];
4040 bufR = buffer[1];
4042 if( (void *)F2610 != cur_chip ){
4043 cur_chip = (void *)F2610;
4044 State = &OPN->ST;
4045 cch[0] = &F2610->CH[1];
4046 cch[1] = &F2610->CH[2];
4047 cch[2] = &F2610->CH[4];
4048 cch[3] = &F2610->CH[5];
4049 /* setup adpcm rom address */
4050 pcmbufA = F2610->pcmbuf;
4051 pcmsizeA = F2610->pcm_size;
4054 #ifdef YM2610B_WARNING
4055 #define FM_KEY_IS(SLOT) ((SLOT)->key)
4056 #define FM_MSG_YM2610B "YM2610-%d.CH%d is playing,Check whether the type of the chip is YM2610B\n"
4057 /* Check YM2610B warning message */
4058 if( FM_KEY_IS(&F2610->CH[0].SLOT[3]) )
4059 LOG(LOG_WAR,(FM_MSG_YM2610B,num,0));
4060 if( FM_KEY_IS(&F2610->CH[3].SLOT[3]) )
4061 LOG(LOG_WAR,(FM_MSG_YM2610B,num,3));
4062 #endif
4064 /* refresh PG and EG */
4065 refresh_fc_eg_chan( OPN, cch[0] );
4066 if( (State->mode & 0xc0) )
4068 /* 3SLOT MODE */
4069 if( cch[1]->SLOT[SLOT1].Incr==-1)
4071 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
4072 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
4073 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
4074 refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT4] , cch[1]->fc , cch[1]->kcode );
4076 }else refresh_fc_eg_chan( OPN, cch[1] );
4077 refresh_fc_eg_chan( OPN, cch[2] );
4078 refresh_fc_eg_chan( OPN, cch[3] );
4080 /* buffering */
4081 for(i=0; i < length ; i++)
4084 advance_lfo(OPN);
4086 /* clear output acc. */
4087 out_adpcm[OUTD_LEFT] = out_adpcm[OUTD_RIGHT]= out_adpcm[OUTD_CENTER] = 0;
4088 out_delta[OUTD_LEFT] = out_delta[OUTD_RIGHT]= out_delta[OUTD_CENTER] = 0;
4089 /* clear outputs */
4090 out_fm[1] = 0;
4091 out_fm[2] = 0;
4092 out_fm[4] = 0;
4093 out_fm[5] = 0;
4095 /* advance envelope generator */
4096 OPN->eg_timer += OPN->eg_timer_add;
4097 while (OPN->eg_timer >= OPN->eg_timer_overflow)
4099 OPN->eg_timer -= OPN->eg_timer_overflow;
4100 OPN->eg_cnt++;
4102 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
4103 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
4104 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
4105 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
4108 /* calculate FM */
4109 chan_calc(OPN, cch[0], 1 ); /*remapped to 1*/
4110 chan_calc(OPN, cch[1], 2 ); /*remapped to 2*/
4111 chan_calc(OPN, cch[2], 4 ); /*remapped to 4*/
4112 chan_calc(OPN, cch[3], 5 ); /*remapped to 5*/
4114 /* deltaT ADPCM */
4115 if( DELTAT->portstate&0x80 )
4116 YM_DELTAT_ADPCM_CALC(DELTAT);
4118 /* ADPCMA */
4119 for( j = 0; j < 6; j++ )
4121 if( F2610->adpcm[j].flag )
4122 ADPCMA_calc_chan( F2610, &F2610->adpcm[j]);
4125 /* buffering */
4127 int lt,rt;
4129 lt = out_adpcm[OUTD_LEFT] + out_adpcm[OUTD_CENTER];
4130 rt = out_adpcm[OUTD_RIGHT] + out_adpcm[OUTD_CENTER];
4131 lt += (out_delta[OUTD_LEFT] + out_delta[OUTD_CENTER])>>9;
4132 rt += (out_delta[OUTD_RIGHT] + out_delta[OUTD_CENTER])>>9;
4135 lt += ((out_fm[1]>>1) & OPN->pan[2]); /* the shift right was verified on real chip */
4136 rt += ((out_fm[1]>>1) & OPN->pan[3]);
4137 lt += ((out_fm[2]>>1) & OPN->pan[4]);
4138 rt += ((out_fm[2]>>1) & OPN->pan[5]);
4140 lt += ((out_fm[4]>>1) & OPN->pan[8]);
4141 rt += ((out_fm[4]>>1) & OPN->pan[9]);
4142 lt += ((out_fm[5]>>1) & OPN->pan[10]);
4143 rt += ((out_fm[5]>>1) & OPN->pan[11]);
4146 lt >>= FINAL_SH;
4147 rt >>= FINAL_SH;
4149 Limit( lt, MAXOUT, MINOUT );
4150 Limit( rt, MAXOUT, MINOUT );
4152 #ifdef SAVE_SAMPLE
4153 SAVE_ALL_CHANNELS
4154 #endif
4156 /* buffering */
4157 bufL[i] = lt;
4158 bufR[i] = rt;
4161 /* timer A control */
4162 INTERNAL_TIMER_A( State , cch[1] )
4164 INTERNAL_TIMER_B(State,length)
4168 #if BUILD_YM2610B
4169 /* Generate samples for one of the YM2610Bs */
4170 void YM2610BUpdateOne(int num, INT16 **buffer, int length)
4172 YM2610 *F2610 = &(FM2610[num]);
4173 FM_OPN *OPN = &(FM2610[num].OPN);
4174 YM_DELTAT *DELTAT = &(FM2610[num].deltaT);
4175 int i,j;
4176 FMSAMPLE *bufL,*bufR;
4178 /* buffer setup */
4179 bufL = buffer[0];
4180 bufR = buffer[1];
4182 if( (void *)F2610 != cur_chip ){
4183 cur_chip = (void *)F2610;
4184 State = &OPN->ST;
4185 cch[0] = &F2610->CH[0];
4186 cch[1] = &F2610->CH[1];
4187 cch[2] = &F2610->CH[2];
4188 cch[3] = &F2610->CH[3];
4189 cch[4] = &F2610->CH[4];
4190 cch[5] = &F2610->CH[5];
4191 /* setup adpcm rom address */
4192 pcmbufA = F2610->pcmbuf;
4193 pcmsizeA = F2610->pcm_size;
4197 /* refresh PG and EG */
4198 refresh_fc_eg_chan( OPN, cch[0] );
4199 refresh_fc_eg_chan( OPN, cch[1] );
4200 if( (State->mode & 0xc0) )
4202 /* 3SLOT MODE */
4203 if( cch[2]->SLOT[SLOT1].Incr==-1)
4205 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
4206 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
4207 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
4208 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
4210 }else refresh_fc_eg_chan( OPN, cch[2] );
4211 refresh_fc_eg_chan( OPN, cch[3] );
4212 refresh_fc_eg_chan( OPN, cch[4] );
4213 refresh_fc_eg_chan( OPN, cch[5] );
4215 /* buffering */
4216 for(i=0; i < length ; i++)
4219 advance_lfo(OPN);
4221 /* clear output acc. */
4222 out_adpcm[OUTD_LEFT] = out_adpcm[OUTD_RIGHT]= out_adpcm[OUTD_CENTER] = 0;
4223 out_delta[OUTD_LEFT] = out_delta[OUTD_RIGHT]= out_delta[OUTD_CENTER] = 0;
4224 /* clear outputs */
4225 out_fm[0] = 0;
4226 out_fm[1] = 0;
4227 out_fm[2] = 0;
4228 out_fm[3] = 0;
4229 out_fm[4] = 0;
4230 out_fm[5] = 0;
4232 /* advance envelope generator */
4233 OPN->eg_timer += OPN->eg_timer_add;
4234 while (OPN->eg_timer >= OPN->eg_timer_overflow)
4236 OPN->eg_timer -= OPN->eg_timer_overflow;
4237 OPN->eg_cnt++;
4239 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
4240 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
4241 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
4242 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
4243 advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]);
4244 advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]);
4247 /* calculate FM */
4248 chan_calc(OPN, cch[0], 0 );
4249 chan_calc(OPN, cch[1], 1 );
4250 chan_calc(OPN, cch[2], 2 );
4251 chan_calc(OPN, cch[3], 3 );
4252 chan_calc(OPN, cch[4], 4 );
4253 chan_calc(OPN, cch[5], 5 );
4255 /* deltaT ADPCM */
4256 if( DELTAT->portstate&0x80 )
4257 YM_DELTAT_ADPCM_CALC(DELTAT);
4259 /* ADPCMA */
4260 for( j = 0; j < 6; j++ )
4262 if( F2610->adpcm[j].flag )
4263 ADPCMA_calc_chan( F2610, &F2610->adpcm[j]);
4266 /* buffering */
4268 int lt,rt;
4270 lt = out_adpcm[OUTD_LEFT] + out_adpcm[OUTD_CENTER];
4271 rt = out_adpcm[OUTD_RIGHT] + out_adpcm[OUTD_CENTER];
4272 lt += (out_delta[OUTD_LEFT] + out_delta[OUTD_CENTER])>>9;
4273 rt += (out_delta[OUTD_RIGHT] + out_delta[OUTD_CENTER])>>9;
4275 lt += ((out_fm[0]>>1) & OPN->pan[0]); /* the shift right is verified on YM2610 */
4276 rt += ((out_fm[0]>>1) & OPN->pan[1]);
4277 lt += ((out_fm[1]>>1) & OPN->pan[2]);
4278 rt += ((out_fm[1]>>1) & OPN->pan[3]);
4279 lt += ((out_fm[2]>>1) & OPN->pan[4]);
4280 rt += ((out_fm[2]>>1) & OPN->pan[5]);
4281 lt += ((out_fm[3]>>1) & OPN->pan[6]);
4282 rt += ((out_fm[3]>>1) & OPN->pan[7]);
4283 lt += ((out_fm[4]>>1) & OPN->pan[8]);
4284 rt += ((out_fm[4]>>1) & OPN->pan[9]);
4285 lt += ((out_fm[5]>>1) & OPN->pan[10]);
4286 rt += ((out_fm[5]>>1) & OPN->pan[11]);
4289 lt >>= FINAL_SH;
4290 rt >>= FINAL_SH;
4292 Limit( lt, MAXOUT, MINOUT );
4293 Limit( rt, MAXOUT, MINOUT );
4295 #ifdef SAVE_SAMPLE
4296 SAVE_ALL_CHANNELS
4297 #endif
4299 /* buffering */
4300 bufL[i] = lt;
4301 bufR[i] = rt;
4304 /* timer A control */
4305 INTERNAL_TIMER_A( State , cch[2] )
4307 INTERNAL_TIMER_B(State,length)
4310 #endif /* BUILD_YM2610B */
4313 #ifdef _STATE_H
4314 static void YM2610_postload(void)
4316 int num , r;
4318 for(num=0;num<YM2610NumChips;num++)
4320 YM2610 *F2610 = &(FM2610[num]);
4321 /* SSG registers */
4322 for(r=0;r<16;r++)
4324 SSGWrite(num,0,r);
4325 SSGWrite(num,1,F2610->REGS[r]);
4328 /* OPN registers */
4329 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
4330 for(r=0x30;r<0x9e;r++)
4331 if((r&3) != 3)
4333 OPNWriteReg(&F2610->OPN,r,F2610->REGS[r]);
4334 OPNWriteReg(&F2610->OPN,r|0x100,F2610->REGS[r|0x100]);
4336 /* FB / CONNECT , L / R / AMS / PMS */
4337 for(r=0xb0;r<0xb6;r++)
4338 if((r&3) != 3)
4340 OPNWriteReg(&F2610->OPN,r,F2610->REGS[r]);
4341 OPNWriteReg(&F2610->OPN,r|0x100,F2610->REGS[r|0x100]);
4343 /* FM channels */
4344 /*FM_channel_postload(F2610->CH,6);*/
4346 /* rhythm(ADPCMA) */
4347 FM_ADPCMAWrite(F2610,1,F2610->REGS[0x101]);
4348 for( r=0 ; r<6 ; r++)
4350 FM_ADPCMAWrite(F2610,r+0x08,F2610->REGS[r+0x108]);
4351 FM_ADPCMAWrite(F2610,r+0x10,F2610->REGS[r+0x110]);
4352 FM_ADPCMAWrite(F2610,r+0x18,F2610->REGS[r+0x118]);
4353 FM_ADPCMAWrite(F2610,r+0x20,F2610->REGS[r+0x120]);
4354 FM_ADPCMAWrite(F2610,r+0x28,F2610->REGS[r+0x128]);
4356 /* Delta-T ADPCM unit */
4357 YM_DELTAT_postload(&F2610->deltaT , &F2610->REGS[0x010] );
4359 cur_chip = NULL;
4362 static void YM2610_save_state(void)
4364 int num;
4365 const char statename[] = "YM2610";
4367 for(num=0;num<YM2610NumChips;num++)
4369 YM2610 *F2610 = &(FM2610[num]);
4371 state_save_register_UINT8 (statename, num, "regs" , F2610->REGS , 512);
4372 FMsave_state_st(statename,num,&FM2610[num].OPN.ST);
4373 FMsave_state_channel(statename,num,FM2610[num].CH,6);
4374 /* 3slots */
4375 state_save_register_UINT32(statename, num, "slot3fc" , F2610->OPN.SL3.fc , 3);
4376 state_save_register_UINT8 (statename, num, "slot3fh" , &F2610->OPN.SL3.fn_h, 1);
4377 state_save_register_UINT8 (statename, num, "slot3kc" , F2610->OPN.SL3.kcode, 3);
4378 /* address register1 */
4379 state_save_register_UINT8 (statename, num, "addr_A1" , &F2610->addr_A1, 1);
4381 state_save_register_UINT8 (statename, num, "arrivedFlag", &F2610->adpcm_arrivedEndAddress , 1);
4382 /* rythm(ADPCMA) */
4383 FMsave_state_adpcma(statename,num,F2610->adpcm);
4384 /* Delta-T ADPCM unit */
4385 YM_DELTAT_savestate(statename,num,&FM2610[num].deltaT);
4387 state_save_register_func_postload(YM2610_postload);
4389 #endif /* _STATE_H */
4391 static void YM2610_deltat_status_set(UINT8 which, UINT8 changebits)
4393 FM2610[which].adpcm_arrivedEndAddress |= changebits;
4395 static void YM2610_deltat_status_reset(UINT8 which, UINT8 changebits)
4397 FM2610[which].adpcm_arrivedEndAddress &= (~changebits);
4400 int YM2610Init(int num, int clock, int rate,
4401 void **pcmroma,int *pcmsizea,void **pcmromb,int *pcmsizeb,
4402 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
4405 int i;
4407 if (FM2610) return (-1); /* duplicate init. */
4408 cur_chip = NULL; /* hiro-shi!! */
4410 YM2610NumChips = num;
4412 /* allocate extend state space */
4413 if( (FM2610 = (YM2610 *)malloc(sizeof(YM2610) * YM2610NumChips))==NULL)
4414 return (-1);
4415 /* clear */
4416 memset(FM2610,0,sizeof(YM2610) * YM2610NumChips);
4417 /* allocate total level table (128kb space) */
4418 if( !init_tables() )
4420 if (FM2610) {
4421 free( FM2610 );
4422 FM2610 = NULL;
4424 return (-1);
4427 for ( i = 0 ; i < YM2610NumChips; i++ ) {
4428 YM2610 *F2610 = &(FM2610[i]);
4429 /* FM */
4430 F2610->OPN.ST.index = i;
4431 F2610->OPN.type = TYPE_YM2610;
4432 F2610->OPN.P_CH = FM2610[i].CH;
4433 F2610->OPN.ST.clock = clock;
4434 F2610->OPN.ST.rate = rate;
4435 /* Extend handler */
4436 F2610->OPN.ST.Timer_Handler = TimerHandler;
4437 F2610->OPN.ST.IRQ_Handler = IRQHandler;
4438 /* ADPCM */
4439 F2610->pcmbuf = (UINT8 *)(pcmroma[i]);
4440 F2610->pcm_size = pcmsizea[i];
4441 /* DELTA-T */
4442 F2610->deltaT.memory = (UINT8 *)(pcmromb[i]);
4443 F2610->deltaT.memory_size = pcmsizeb[i];
4445 FM2610[i].deltaT.status_set_handler = YM2610_deltat_status_set;
4446 FM2610[i].deltaT.status_reset_handler = YM2610_deltat_status_reset;
4447 FM2610[i].deltaT.status_change_which_chip = i;
4448 FM2610[i].deltaT.status_change_EOS_bit = 0x80; /* status flag: set bit7 on End Of Sample */
4450 YM2610ResetChip(i);
4452 Init_ADPCMATable();
4453 #ifdef _STATE_H
4454 YM2610_save_state();
4455 #endif
4456 return 0;
4459 /* remap sample memory of chip */
4460 void YM2610SetRom(int num, void *pcmroma,int pcmsizea,void *pcmromb,int pcmsizeb)
4462 YM2610 *F2610 = &(FM2610[num]);
4464 /* ADPCM */
4465 F2610->pcmbuf = (UINT8 *)pcmroma;
4466 F2610->pcm_size = pcmsizea;
4467 /* DELTA-T */
4468 F2610->deltaT.memory = (UINT8 *)pcmromb;
4469 F2610->deltaT.memory_size = pcmsizeb;
4471 if( (void *)F2610 == cur_chip ){
4472 pcmbufA = F2610->pcmbuf;
4473 pcmsizeA = F2610->pcm_size;
4477 /* shut down emulator */
4478 void YM2610Shutdown()
4480 if (!FM2610) return;
4482 FMCloseTable();
4483 if (FM2610) {
4484 free(FM2610);
4485 FM2610 = NULL;
4489 /* reset one of chip */
4490 void YM2610ResetChip(int num)
4492 int i;
4493 YM2610 *F2610 = &(FM2610[num]);
4494 FM_OPN *OPN = &(FM2610[num].OPN);
4495 YM_DELTAT *DELTAT = &(FM2610[num].deltaT);
4497 /* Reset Prescaler */
4498 OPNSetPres( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
4499 /* reset SSG section */
4500 SSGReset(OPN->ST.index);
4501 /* status clear */
4502 FM_IRQMASK_SET(&OPN->ST,0x03);
4503 FM_BUSY_CLEAR(&OPN->ST);
4504 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
4506 OPN->eg_timer = 0;
4507 OPN->eg_cnt = 0;
4509 FM_STATUS_RESET(&OPN->ST, 0xff);
4511 reset_channels( &OPN->ST , F2610->CH , 6 );
4512 /* reset OPerator paramater */
4513 for(i = 0xb6 ; i >= 0xb4 ; i-- )
4515 OPNWriteReg(OPN,i ,0xc0);
4516 OPNWriteReg(OPN,i|0x100,0xc0);
4518 for(i = 0xb2 ; i >= 0x30 ; i-- )
4520 OPNWriteReg(OPN,i ,0);
4521 OPNWriteReg(OPN,i|0x100,0);
4523 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
4524 /**** ADPCM work initial ****/
4525 for( i = 0; i < 6 ; i++ ){
4526 F2610->adpcm[i].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/3.0);
4527 F2610->adpcm[i].now_addr = 0;
4528 F2610->adpcm[i].now_step = 0;
4529 F2610->adpcm[i].start = 0;
4530 F2610->adpcm[i].end = 0;
4531 /* F2610->adpcm[i].delta = 21866; */
4532 F2610->adpcm[i].vol_mul = 0;
4533 F2610->adpcm[i].pan = &out_adpcm[OUTD_CENTER]; /* default center */
4534 F2610->adpcm[i].flagMask = 1<<i;
4535 F2610->adpcm[i].flag = 0;
4536 F2610->adpcm[i].adpcm_acc = 0;
4537 F2610->adpcm[i].adpcm_step= 0;
4538 F2610->adpcm[i].adpcm_out = 0;
4540 F2610->adpcmTL = 0x3f;
4542 F2610->adpcm_arrivedEndAddress = 0;
4544 /* DELTA-T unit */
4545 DELTAT->freqbase = OPN->ST.freqbase;
4546 DELTAT->output_pointer = out_delta;
4547 DELTAT->portshift = 8; /* allways 8bits shift */
4548 DELTAT->output_range = 1<<23;
4549 YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER,YM_DELTAT_EMULATION_MODE_YM2610);
4552 /* YM2610 write */
4553 /* n = number */
4554 /* a = address */
4555 /* v = value */
4556 int YM2610Write(int n, int a, UINT8 v)
4558 YM2610 *F2610 = &(FM2610[n]);
4559 FM_OPN *OPN = &(FM2610[n].OPN);
4560 int addr;
4561 int ch;
4563 v &= 0xff; /* adjust to 8 bit bus */
4565 switch( a&3 ){
4566 case 0: /* address port 0 */
4567 OPN->ST.address = v;
4568 F2610->addr_A1 = 0;
4570 /* Write register to SSG emulator */
4571 if( v < 16 ) SSGWrite(n,0,v);
4572 break;
4574 case 1: /* data port 0 */
4575 if (F2610->addr_A1 != 0)
4576 break; /* verified on real YM2608 */
4578 addr = OPN->ST.address;
4579 #ifdef _STATE_H
4580 F2610->REGS[addr] = v;
4581 #endif
4582 switch(addr & 0xf0)
4584 case 0x00: /* SSG section */
4585 /* Write data to SSG emulator */
4586 SSGWrite(n,a,v);
4587 break;
4588 case 0x10: /* DeltaT ADPCM */
4589 YM2610UpdateReq(n);
4591 switch(addr)
4593 case 0x10: /* control 1 */
4594 case 0x11: /* control 2 */
4595 case 0x12: /* start address L */
4596 case 0x13: /* start address H */
4597 case 0x14: /* stop address L */
4598 case 0x15: /* stop address H */
4600 case 0x19: /* delta-n L */
4601 case 0x1a: /* delta-n H */
4602 case 0x1b: /* volume */
4604 YM_DELTAT_ADPCM_Write(&F2610->deltaT,addr-0x10,v);
4606 break;
4608 case 0x1c: /* FLAG CONTROL : Extend Status Clear/Mask */
4610 UINT8 statusmask = ~v;
4611 /* set arrived flag mask */
4612 for(ch=0;ch<6;ch++)
4613 F2610->adpcm[ch].flagMask = statusmask&(1<<ch);
4615 F2610->deltaT.status_change_EOS_bit = statusmask & 0x80; /* status flag: set bit7 on End Of Sample */
4617 /* clear arrived flag */
4618 F2610->adpcm_arrivedEndAddress &= statusmask;
4620 break;
4622 default:
4623 logerror("YM2610: write to unknown deltat register %02x val=%02x\n",addr,v);
4624 break;
4627 break;
4628 case 0x20: /* Mode Register */
4629 YM2610UpdateReq(n);
4630 OPNWriteMode(OPN,addr,v);
4631 break;
4632 default: /* OPN section */
4633 YM2610UpdateReq(n);
4634 /* write register */
4635 OPNWriteReg(OPN,addr,v);
4637 break;
4639 case 2: /* address port 1 */
4640 OPN->ST.address = v;
4641 F2610->addr_A1 = 1;
4642 break;
4644 case 3: /* data port 1 */
4645 if (F2610->addr_A1 != 1)
4646 break; /* verified on real YM2608 */
4648 YM2610UpdateReq(n);
4649 addr = OPN->ST.address;
4650 #ifdef _STATE_H
4651 F2610->REGS[addr | 0x100] = v;
4652 #endif
4653 if( addr < 0x30 )
4654 /* 100-12f : ADPCM A section */
4655 FM_ADPCMAWrite(F2610,addr,v);
4656 else
4657 OPNWriteReg(OPN,addr | 0x100,v);
4659 return OPN->ST.irq;
4662 UINT8 YM2610Read(int n,int a)
4664 YM2610 *F2610 = &(FM2610[n]);
4665 int addr = F2610->OPN.ST.address;
4666 UINT8 ret = 0;
4668 switch( a&3){
4669 case 0: /* status 0 : YM2203 compatible */
4670 ret = FM_STATUS_FLAG(&F2610->OPN.ST) & 0x83;
4671 break;
4672 case 1: /* data 0 */
4673 if( addr < 16 ) ret = SSGRead(n);
4674 if( addr == 0xff ) ret = 0x01;
4675 break;
4676 case 2: /* status 1 : ADPCM status */
4677 /* ADPCM STATUS (arrived End Address) */
4678 /* B,--,A5,A4,A3,A2,A1,A0 */
4679 /* B = ADPCM-B(DELTA-T) arrived end address */
4680 /* A0-A5 = ADPCM-A arrived end address */
4681 ret = F2610->adpcm_arrivedEndAddress;
4682 break;
4683 case 3:
4684 ret = 0;
4685 break;
4687 return ret;
4690 int YM2610TimerOver(int n,int c)
4692 YM2610 *F2610 = &(FM2610[n]);
4694 if( c )
4695 { /* Timer B */
4696 TimerBOver( &(F2610->OPN.ST) );
4698 else
4699 { /* Timer A */
4700 YM2610UpdateReq(n);
4701 /* timer update */
4702 TimerAOver( &(F2610->OPN.ST) );
4703 /* CSM mode key,TL controll */
4704 if( F2610->OPN.ST.mode & 0x80 )
4705 { /* CSM mode total level latch and auto key on */
4706 CSMKeyControll( F2610->OPN.type, &(F2610->CH[2]) );
4709 return F2610->OPN.ST.irq;
4712 #endif /* (BUILD_YM2610||BUILD_YM2610B) */
4716 #if BUILD_YM2612
4717 /*******************************************************************************/
4718 /* YM2612 local section */
4719 /*******************************************************************************/
4720 /* here's the virtual YM2612 */
4721 typedef struct
4723 UINT8 REGS[512]; /* registers */
4724 FM_OPN OPN; /* OPN state */
4725 FM_CH CH[6]; /* channel state */
4726 UINT8 addr_A1; /* address line A1 */
4728 /* dac output (YM2612) */
4729 int dacen;
4730 INT32 dacout;
4731 } YM2612;
4733 static int YM2612NumChips; /* total chip */
4734 static YM2612 *FM2612=NULL; /* array of YM2612's */
4736 static int dacen;
4738 /* Generate samples for one of the YM2612s */
4739 void YM2612UpdateOne(int num, INT16 *buffer, unsigned int length,
4740 unsigned int volume, int loud)
4742 YM2612 *F2612 = &(FM2612[num]);
4743 FM_OPN *OPN = &(FM2612[num].OPN);
4744 unsigned int i;
4745 INT32 dacout = F2612->dacout;
4747 if( (void *)F2612 != cur_chip ){
4748 cur_chip = (void *)F2612;
4749 State = &OPN->ST;
4750 cch[0] = &F2612->CH[0];
4751 cch[1] = &F2612->CH[1];
4752 cch[2] = &F2612->CH[2];
4753 cch[3] = &F2612->CH[3];
4754 cch[4] = &F2612->CH[4];
4755 cch[5] = &F2612->CH[5];
4756 /* DAC mode */
4757 dacen = F2612->dacen;
4761 /* refresh PG and EG */
4762 refresh_fc_eg_chan( OPN, cch[0] );
4763 refresh_fc_eg_chan( OPN, cch[1] );
4764 if( (State->mode & 0xc0) )
4766 /* 3SLOT MODE */
4767 if( cch[2]->SLOT[SLOT1].Incr==-1)
4769 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
4770 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
4771 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
4772 refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
4774 }else refresh_fc_eg_chan( OPN, cch[2] );
4775 refresh_fc_eg_chan( OPN, cch[3] );
4776 refresh_fc_eg_chan( OPN, cch[4] );
4777 refresh_fc_eg_chan( OPN, cch[5] );
4779 /* buffering */
4780 for(i=0; i < length ; i++)
4783 advance_lfo(OPN);
4785 /* clear outputs */
4786 out_fm[0] = 0;
4787 out_fm[1] = 0;
4788 out_fm[2] = 0;
4789 out_fm[3] = 0;
4790 out_fm[4] = 0;
4791 out_fm[5] = 0;
4793 /* calculate FM */
4794 chan_calc(OPN, cch[0], 0 );
4795 chan_calc(OPN, cch[1], 1 );
4796 chan_calc(OPN, cch[2], 2 );
4797 chan_calc(OPN, cch[3], 3 );
4798 chan_calc(OPN, cch[4], 4 );
4799 if( dacen )
4800 *cch[5]->connect4 += dacout;
4801 else
4802 chan_calc(OPN, cch[5], 5 );
4804 /* advance envelope generator */
4805 OPN->eg_timer += OPN->eg_timer_add;
4806 while (OPN->eg_timer >= OPN->eg_timer_overflow)
4808 OPN->eg_timer -= OPN->eg_timer_overflow;
4809 OPN->eg_cnt++;
4811 advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]);
4812 advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]);
4813 advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]);
4814 advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]);
4815 advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]);
4816 advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]);
4820 int32_t lt, rt;
4822 lt = ((out_fm[0]>>0) & OPN->pan[0]);
4823 rt = ((out_fm[0]>>0) & OPN->pan[1]);
4824 lt += ((out_fm[1]>>0) & OPN->pan[2]);
4825 rt += ((out_fm[1]>>0) & OPN->pan[3]);
4826 lt += ((out_fm[2]>>0) & OPN->pan[4]);
4827 rt += ((out_fm[2]>>0) & OPN->pan[5]);
4828 lt += ((out_fm[3]>>0) & OPN->pan[6]);
4829 rt += ((out_fm[3]>>0) & OPN->pan[7]);
4830 lt += ((out_fm[4]>>0) & OPN->pan[8]);
4831 rt += ((out_fm[4]>>0) & OPN->pan[9]);
4832 lt += ((out_fm[5]>>0) & OPN->pan[10]);
4833 rt += ((out_fm[5]>>0) & OPN->pan[11]);
4835 lt >>= FINAL_SH;
4836 rt >>= FINAL_SH;
4838 #if 0
4839 Limit( lt, MAXOUT, MINOUT );
4840 Limit( rt, MAXOUT, MINOUT );
4841 #endif
4843 #ifdef SAVE_SAMPLE
4844 SAVE_ALL_CHANNELS
4845 #endif
4847 /* Mix with buffer. */
4848 lt += *buffer;
4849 /* Make it louder. */
4850 if (loud)
4851 lt = ((lt * 3) >> 1);
4852 /* Lower volume? */
4853 if (volume != 100)
4854 lt = ((lt * (int)volume) / 100);
4855 /* Hard clipping for signed 16-bit output. */
4856 lt = ((abs(lt + 32767) - abs(lt - 32767)) >> 1);
4857 *(buffer++) = lt;
4859 rt += *buffer;
4860 if (loud)
4861 rt = ((rt * 3) >> 1);
4862 if (volume != 100)
4863 rt = ((rt * (int)volume) / 100);
4864 rt = ((abs(rt + 32767) - abs(rt - 32767)) >> 1);
4865 *(buffer++) = rt;
4868 /* timer A control */
4869 INTERNAL_TIMER_A(OPN->type, State, cch[2])
4871 INTERNAL_TIMER_B(State,length)
4875 #ifdef _STATE_H
4876 static void YM2612_postload(void)
4878 int num , r;
4880 for(num=0;num<YM2612NumChips;num++)
4882 /* DAC data & port */
4883 FM2612[num].dacout = ((int)FM2612[num].REGS[0x2a] - 0x80) << 6; /* level unknown */
4884 FM2612[num].dacen = FM2612[num].REGS[0x2d] & 0x80;
4885 /* OPN registers */
4886 /* DT / MULTI , TL , KS / AR , AMON / DR , SR , SL / RR , SSG-EG */
4887 for(r=0x30;r<0x9e;r++)
4888 if((r&3) != 3)
4890 OPNWriteReg(&FM2612[num].OPN,r,FM2612[num].REGS[r]);
4891 OPNWriteReg(&FM2612[num].OPN,r|0x100,FM2612[num].REGS[r|0x100]);
4893 /* FB / CONNECT , L / R / AMS / PMS */
4894 for(r=0xb0;r<0xb6;r++)
4895 if((r&3) != 3)
4897 OPNWriteReg(&FM2612[num].OPN,r,FM2612[num].REGS[r]);
4898 OPNWriteReg(&FM2612[num].OPN,r|0x100,FM2612[num].REGS[r|0x100]);
4900 /* channels */
4901 /*FM_channel_postload(FM2612[num].CH,6);*/
4903 cur_chip = NULL;
4906 static void YM2612_save_state(void)
4908 int num;
4909 const char statename[] = "YM2612";
4911 for(num=0;num<YM2612NumChips;num++)
4913 state_save_register_UINT8 (statename, num, "regs" , FM2612[num].REGS , 512);
4914 FMsave_state_st(statename,num,&FM2612[num].OPN.ST);
4915 FMsave_state_channel(statename,num,FM2612[num].CH,6);
4916 /* 3slots */
4917 state_save_register_UINT32 (statename, num, "slot3fc" , FM2612[num].OPN.SL3.fc , 3);
4918 state_save_register_UINT8 (statename, num, "slot3fh" , &FM2612[num].OPN.SL3.fn_h, 1);
4919 state_save_register_UINT8 (statename, num, "slot3kc" , FM2612[num].OPN.SL3.kcode, 3);
4920 /* address register1 */
4921 state_save_register_UINT8 (statename, num, "addr_A1" , &FM2612[num].addr_A1, 1);
4923 state_save_register_func_postload(YM2612_postload);
4925 #endif /* _STATE_H */
4927 /* initialize YM2612 emulator(s) */
4928 int YM2612Init(int num, int clock, int rate, int mjazz,
4929 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
4931 int i;
4933 if (FM2612) return (-1); /* duplicate init. */
4934 cur_chip = NULL; /* hiro-shi!! */
4936 YM2612NumChips = num;
4938 /* allocate extend state space */
4939 if( (FM2612 = (YM2612 *)malloc(sizeof(YM2612) * YM2612NumChips))==NULL)
4940 return (-1);
4941 /* clear */
4942 memset(FM2612,0,sizeof(YM2612) * YM2612NumChips);
4943 /* allocate total level table (128kb space) */
4944 if( !init_tables() )
4946 if (FM2612) {
4947 free( FM2612 );
4948 FM2612 = NULL;
4950 return (-1);
4953 for ( i = 0 ; i < YM2612NumChips; i++ ) {
4954 FM2612[i].OPN.ST.index = i;
4955 FM2612[i].OPN.type = TYPE_YM2612;
4956 FM2612[i].OPN.P_CH = FM2612[i].CH;
4957 FM2612[i].OPN.ST.clock = clock;
4958 FM2612[i].OPN.ST.rate = rate;
4959 if (mjazz)
4960 FM2612[i].OPN.ST.rate <<= i;
4961 /* FM2612[i].OPN.ST.irq = 0; */
4962 /* FM2612[i].OPN.ST.status = 0; */
4963 /* Extend handler */
4964 FM2612[i].OPN.ST.Timer_Handler = TimerHandler;
4965 FM2612[i].OPN.ST.IRQ_Handler = IRQHandler;
4966 YM2612ResetChip(i);
4968 #ifdef _STATE_H
4969 YM2612_save_state();
4970 #endif
4971 return 0;
4974 /* shut down emulator */
4975 void YM2612Shutdown()
4977 if (!FM2612) return;
4979 FMCloseTable();
4980 if (FM2612) {
4981 free(FM2612);
4982 FM2612 = NULL;
4986 /* reset one of chip */
4987 void YM2612ResetChip(int num)
4989 int i;
4990 YM2612 *F2612 = &(FM2612[num]);
4991 FM_OPN *OPN = &(FM2612[num].OPN);
4993 OPNSetPres( OPN, 6*24, 6*24, 0);
4994 /* status clear */
4995 FM_IRQMASK_SET(&OPN->ST,0x03);
4996 FM_BUSY_CLEAR(&OPN->ST);
4997 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
4999 OPN->eg_timer = 0;
5000 OPN->eg_cnt = 0;
5002 FM_STATUS_RESET(&OPN->ST, 0xff);
5004 reset_channels( &OPN->ST , &F2612->CH[0] , 6 );
5005 for(i = 0xb6 ; i >= 0xb4 ; i-- )
5007 OPNWriteReg(OPN,i ,0xc0);
5008 OPNWriteReg(OPN,i|0x100,0xc0);
5010 for(i = 0xb2 ; i >= 0x30 ; i-- )
5012 OPNWriteReg(OPN,i ,0);
5013 OPNWriteReg(OPN,i|0x100,0);
5015 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
5016 /* DAC mode clear */
5017 F2612->dacen = 0;
5020 /* YM2612 write */
5021 /* n = number */
5022 /* a = address */
5023 /* v = value */
5024 int YM2612Write(int n, int a, UINT8 v)
5026 YM2612 *F2612 = &(FM2612[n]);
5027 int addr;
5029 v &= 0xff; /* adjust to 8 bit bus */
5031 switch( a&3){
5032 case 0: /* address port 0 */
5033 F2612->OPN.ST.address = v;
5034 F2612->addr_A1 = 0;
5035 break;
5037 case 1: /* data port 0 */
5038 if (F2612->addr_A1 != 0)
5039 break; /* verified on real YM2608 */
5041 addr = F2612->OPN.ST.address;
5042 /*#ifdef _STATE_H*/
5043 F2612->REGS[addr] = v;
5044 /*#endif*/
5045 switch( addr & 0xf0 )
5047 case 0x20: /* 0x20-0x2f Mode */
5048 switch( addr )
5050 case 0x2a: /* DAC data (YM2612) */
5051 YM2612UpdateReq(n);
5052 F2612->dacout = ((int)v - 0x80) << 6; /* level unknown */
5053 break;
5054 case 0x2b: /* DAC Sel (YM2612) */
5055 /* b7 = dac enable */
5056 F2612->dacen = v & 0x80;
5057 cur_chip = NULL;
5058 break;
5059 default: /* OPN section */
5060 YM2612UpdateReq(n);
5061 /* write register */
5062 OPNWriteMode(&(F2612->OPN),addr,v);
5064 break;
5065 default: /* 0x30-0xff OPN section */
5066 YM2612UpdateReq(n);
5067 /* write register */
5068 OPNWriteReg(&(F2612->OPN),addr,v);
5070 break;
5072 case 2: /* address port 1 */
5073 F2612->OPN.ST.address = v;
5074 F2612->addr_A1 = 1;
5075 break;
5077 case 3: /* data port 1 */
5078 if (F2612->addr_A1 != 1)
5079 break; /* verified on real YM2608 */
5081 addr = F2612->OPN.ST.address;
5082 /*#ifdef _STATE_H*/
5083 F2612->REGS[addr | 0x100] = v;
5084 /*#endif*/
5085 YM2612UpdateReq(n);
5086 OPNWriteReg(&(F2612->OPN),addr | 0x100,v);
5087 break;
5089 return F2612->OPN.ST.irq;
5092 UINT8 YM2612Read(int n,int a)
5094 YM2612 *F2612 = &(FM2612[n]);
5096 switch( a&3){
5097 case 0: /* status 0 */
5098 return FM_STATUS_FLAG(&F2612->OPN.ST);
5099 case 1:
5100 case 2:
5101 case 3:
5102 LOG(LOG_WAR,("YM2612 #%d:A=%d read unmapped area\n",n,a));
5103 return FM_STATUS_FLAG(&F2612->OPN.ST);
5105 return 0;
5108 int YM2612TimerOver(int n,int c)
5110 YM2612 *F2612 = &(FM2612[n]);
5112 if( c )
5113 { /* Timer B */
5114 TimerBOver( &(F2612->OPN.ST) );
5116 else
5117 { /* Timer A */
5118 YM2612UpdateReq(n);
5119 /* timer update */
5120 TimerAOver( &(F2612->OPN.ST) );
5121 /* CSM mode key,TL controll */
5122 if( F2612->OPN.ST.mode & 0x80 )
5123 { /* CSM mode total level latch and auto key on */
5124 CSMKeyControll( F2612->OPN.type, &(F2612->CH[2]) );
5127 return F2612->OPN.ST.irq;
5130 /* Implemented by zamaz for dgen */
5131 void YM2612_dump(int num, uint8_t buf[512])
5133 YM2612 *F2612 = &(FM2612[num]);
5135 memcpy(buf, F2612->REGS, 512);
5138 /* Implemented by zamaz for dgen */
5139 void YM2612_restore(int num, uint8_t buf[512])
5141 YM2612 *F2612 = &(FM2612[num]);
5142 unsigned int r;
5144 memcpy(F2612->REGS, buf, 512);
5145 /* See YM2612_postload(). */
5146 F2612->dacout = ((buf[0x2a] - 0x80) << 6);
5147 F2612->dacen = (buf[0x2d] & 0x80);
5148 for (r = 0x30; (r != 0x9e); ++r) {
5149 if ((r & 3) == 3)
5150 continue;
5151 OPNWriteReg(&F2612->OPN, r, buf[r]);
5152 OPNWriteReg(&F2612->OPN, (r | 0x100), buf[(r | 0x100)]);
5154 for (r = 0xb0; (r != 0xb6); ++r) {
5155 if ((r & 3) == 3)
5156 continue;
5157 OPNWriteReg(&F2612->OPN, r, buf[r]);
5158 OPNWriteReg(&F2612->OPN, (r | 0x100), buf[(r | 0x100)]);
5162 // ---------------------------------------------------------------------------
5163 // Everything below this line is for the debugger.
5164 // It can't be in debug.c because it needs the private structs defined here
5165 // ---------------------------------------------------------------------------
5167 #ifdef WITH_DEBUGGER
5170 * I figure it is easier to extract the parameters directly rather
5171 * than have to interpret the structs defined above
5174 /* global ym2612 registers (YMREG_*) */
5175 #define YMREG_LFO 0x22
5176 #define YMREG_TIMER_A1 0x24
5177 #define YMREG_TIMER_A2 0x25
5178 #define YMREG_TIMER_B 0x26
5179 #define YMREG_CH3_TIMERS 0x27
5180 #define YMREG_KEY 0x28
5181 #define YMREG_DAC 0x2a
5182 #define YMREG_DAC_ENABLE 0x2b
5183 #define YMREG_OP_SSG_EG 0x90
5185 /* per channel ym2612 registers (YMREG_CHAN_*) */
5186 #define YMREG_CHAN_FREQ1 0xa0
5187 #define YMREG_CHAN_FREQ2 0xa4
5188 #define YMREG_CHAN_CH3_OP1_FREQ1 0xa2
5189 #define YMREG_CHAN_CH3_OP1_FREQ2 0xa6
5190 #define YMREG_CHAN_CH3_OP2_FREQ1 0xa8
5191 #define YMREG_CHAN_CH3_OP2_FREQ2 0xac
5192 #define YMREG_CHAN_CH3_OP3_FREQ1 0xa9
5193 #define YMREG_CHAN_CH3_OP3_FREQ2 0xad
5194 #define YMREG_CHAN_CH3_OP4_FREQ1 0xaa
5195 #define YMREG_CHAN_CH3_OP4_FREQ2 0xae
5196 #define YMREG_CHAN_FBACK_ALGO 0xb0
5197 #define YMREG_CHAN_LR_AMS_FMS 0xb4
5199 /* per operator um2612 registers (YMREG_OP_*) */
5200 #define YMREG_OP_DT1_MUL 0x30
5201 #define YMREG_OP_TL 0x40
5202 #define YMREG_OP_RS_AR 0x50
5203 #define YMREG_OP_AM_D1R 0x60
5204 #define YMREG_OP_D2R 0x70
5205 #define YMREG_OP_D1L_RR 0x80
5206 #define YMREG_OP_SSG_EG 0x90
5209 * Given a channel return the part (1 or 2) and the channel offset (1-3).
5210 * Eg. Channel 5 is part 2 offset 1
5212 void
5213 debug_get_chan_part_and_offset(uint8_t chan, uint8_t *part, uint8_t *offs)
5215 if ((chan >= 1) && (chan <= 3)) {
5216 *part = 1;
5217 } else if (chan <= 6) {
5218 *part = 2;
5219 } else {
5220 *part = 0;
5221 *offs = 0;
5222 printf("%s: bad channel: %d\n", __func__, chan);
5223 return;
5226 *offs = (chan - 1) % 3;
5229 #define DEBUG_PRINT_GLOBAL_VAL(r, v) printf(" %-15s: 0x%02x\n", r, v);
5230 void debug_show_ym2612_global_regs(uint8_t regs[512])
5232 printf("ym2612 global registers:\n");
5234 DEBUG_PRINT_GLOBAL_VAL("LFO Enable", (regs[YMREG_LFO] & 8) >> 3);
5235 DEBUG_PRINT_GLOBAL_VAL("LFO Freq.", regs[YMREG_LFO] & 7);
5236 DEBUG_PRINT_GLOBAL_VAL("Timer A", (regs[YMREG_TIMER_A1] & 0x3) | (regs[YMREG_TIMER_A2]));
5237 DEBUG_PRINT_GLOBAL_VAL("Timer B", regs[YMREG_TIMER_B]);
5238 DEBUG_PRINT_GLOBAL_VAL("Ch3 Mode",(regs[YMREG_CH3_TIMERS] & 0xa0) >> 6);
5239 DEBUG_PRINT_GLOBAL_VAL("Timer Reset B", (regs[YMREG_CH3_TIMERS] & 0x20) >> 5);
5240 DEBUG_PRINT_GLOBAL_VAL("Timer Reset A", (regs[YMREG_CH3_TIMERS] & 0x10) >> 4);
5241 DEBUG_PRINT_GLOBAL_VAL("Timer Enable B", (regs[YMREG_CH3_TIMERS] & 0x8) >> 3);
5242 DEBUG_PRINT_GLOBAL_VAL("Timer Enable A", (regs[YMREG_CH3_TIMERS] & 0x4) >> 2);
5243 DEBUG_PRINT_GLOBAL_VAL("Timer Load B", (regs[YMREG_CH3_TIMERS] & 0x2) >> 1);
5244 DEBUG_PRINT_GLOBAL_VAL("Timer Load A", regs[YMREG_CH3_TIMERS] & 0x2);
5245 DEBUG_PRINT_GLOBAL_VAL("Operator Enable", (regs[YMREG_KEY] & 0xf0) >> 4);
5246 DEBUG_PRINT_GLOBAL_VAL("Key Enable", regs[YMREG_KEY] & 0xf);
5247 DEBUG_PRINT_GLOBAL_VAL("DAC", regs[YMREG_DAC]);
5248 DEBUG_PRINT_GLOBAL_VAL("DAC Enable", (regs[YMREG_DAC_ENABLE] & 0x80) >> 7);
5251 /* get the address of one of the operator specific registers */
5252 uint8_t debug_get_opn_reg_addr(uint8_t reg, uint8_t ch, uint8_t op)
5254 uint8_t part, ch_offset, addr;
5256 if ((ch < 1) || (ch > 6)) {
5257 printf("%s: bad channel: %u\n", __func__, ch);
5258 return (0);
5261 if ((op < 1) || (op > 4)) {
5262 printf("%s: bad operator: %u\n", __func__, op);
5263 return (0);
5266 debug_get_chan_part_and_offset(ch, &part, &ch_offset);
5267 addr = reg + ((op - 1) * 4) + ch_offset;
5269 if (part > 1)
5270 addr += 0x100; /* part 2 is stored in bytes 256 - 511 */
5272 return addr;
5275 /* show a single slot's (aka operator's) registers (many per channel) */
5276 #define DEBUG_PRINT_OP_VAL(r, v) printf(" %-15s: 0x%02x\n", r, v);
5277 void debug_show_ym2612_operator_regs(uint8_t regs[512], uint8_t ch, uint8_t op)
5279 printf("\n ym2612 channel %u operator %u registers:\n", ch, op);
5281 DEBUG_PRINT_OP_VAL("Detune (DT1)",
5282 (regs[debug_get_opn_reg_addr(YMREG_OP_DT1_MUL, ch, op)] & 0x70) >> 4);
5283 DEBUG_PRINT_OP_VAL("Multiplier (MUL)",
5284 regs[debug_get_opn_reg_addr(YMREG_OP_DT1_MUL, ch, op)] & 0xf);
5285 DEBUG_PRINT_OP_VAL("Total Level (TL)",
5286 regs[debug_get_opn_reg_addr(YMREG_OP_TL, ch, op)] & 0x7f);
5287 DEBUG_PRINT_OP_VAL("Rate Scaling (RS)",
5288 (regs[debug_get_opn_reg_addr(YMREG_OP_RS_AR, ch, op)] & 0xc0) >> 6);
5289 DEBUG_PRINT_OP_VAL("Attack rate (AR)",
5290 regs[debug_get_opn_reg_addr(YMREG_OP_RS_AR, ch, op)] & 0x1f);
5291 DEBUG_PRINT_OP_VAL("AM Enable (AM)",
5292 (regs[debug_get_opn_reg_addr(YMREG_OP_AM_D1R, ch, op)] & 0x80) >> 7);
5293 DEBUG_PRINT_OP_VAL("First Decay Rate (D1R)",
5294 regs[debug_get_opn_reg_addr(YMREG_OP_AM_D1R, ch, op)] & 0x1f);
5295 DEBUG_PRINT_OP_VAL("Second Decay Rate (D2R)",
5296 regs[debug_get_opn_reg_addr(YMREG_OP_D2R, ch, op)] & 0x1f);
5297 DEBUG_PRINT_OP_VAL("Secondary Level (D1L)",
5298 (regs[debug_get_opn_reg_addr(YMREG_OP_D1L_RR, ch, op)] & 0xf0) >> 4);
5299 DEBUG_PRINT_OP_VAL("Release Rate (RR)",
5300 regs[debug_get_opn_reg_addr(YMREG_OP_D1L_RR, ch, op)] & 0xf);
5301 DEBUG_PRINT_OP_VAL("Sega Proproetary (SSG-EG)",
5302 regs[debug_get_opn_reg_addr(YMREG_OP_SSG_EG, ch, op)] & 0xf);
5306 /* get the address of one of the operator specific registers */
5307 uint8_t debug_get_chan_reg_addr(uint8_t reg, uint8_t ch)
5309 uint8_t part, ch_offset;
5311 if ((ch < 1) || (ch > 6)) {
5312 printf("%s: bad channel: %u\n", __func__, ch);
5313 return (0);
5316 debug_get_chan_part_and_offset(ch, &part, &ch_offset);
5317 return (reg + ch_offset + ((part - 1) * 0x100));
5319 /* shows a single channel's regsiters */
5320 #define DEBUG_MAX_OPS 4
5321 #define DEBUG_PRINT_CHAN_VAL(r, v) printf(" %-15s: 0x%02x\n", r, v);
5322 void debug_show_ym2612_chan_regs(uint8_t regs[512], uint8_t ch)
5324 uint8_t op;
5326 printf("\n ym2612 channel %u registers:\n", ch);
5328 DEBUG_PRINT_CHAN_VAL("Octave",
5329 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_FREQ2, ch)]) & 0x38) >> 3);
5331 DEBUG_PRINT_CHAN_VAL("Frequency",
5332 (regs[debug_get_chan_reg_addr(YMREG_CHAN_FREQ2, ch)] & 0x7) << 8 |
5333 regs[debug_get_chan_reg_addr(YMREG_CHAN_FREQ1, ch)]);
5335 /* channel 3 and 6 can have separate freq's per op */
5336 if ((ch % 3) == 0) {
5337 DEBUG_PRINT_CHAN_VAL("Supp. Freq 1",
5338 (regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP1_FREQ2, ch)] & 0x7) << 8 |
5339 regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP1_FREQ1, ch)]);
5340 DEBUG_PRINT_CHAN_VAL("Supp. Octave 1",
5341 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP1_FREQ2, ch)]) & 0x38) >> 3);
5343 DEBUG_PRINT_CHAN_VAL("Supp. Freq 2",
5344 (regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP2_FREQ2, ch)] & 0x7) << 8 |
5345 regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP2_FREQ1, ch)]);
5346 DEBUG_PRINT_CHAN_VAL("Supp. Octave 2",
5347 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP2_FREQ2, ch)]) & 0x38) >> 3);
5349 DEBUG_PRINT_CHAN_VAL("Supp. Freq 3",
5350 (regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP3_FREQ2, ch)] & 0x7) << 8 |
5351 regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP3_FREQ1, ch)]);
5352 DEBUG_PRINT_CHAN_VAL("Supp. Octave 3",
5353 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP3_FREQ2, ch)]) & 0x38) >> 3);
5355 DEBUG_PRINT_CHAN_VAL("Supp. Freq 4",
5356 (regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP3_FREQ2, ch)] & 0x7) << 8 |
5357 regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP3_FREQ1, ch)]);
5358 DEBUG_PRINT_CHAN_VAL("Supp. Octave 4",
5359 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_CH3_OP1_FREQ2, ch)]) & 0x38) >> 3);
5362 DEBUG_PRINT_CHAN_VAL("Feedback",
5363 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_FBACK_ALGO, ch)]) & 0x38) >> 3);
5364 DEBUG_PRINT_CHAN_VAL("Algorithm",
5365 (regs[debug_get_chan_reg_addr(YMREG_CHAN_FBACK_ALGO, ch)]) & 0x3);
5366 DEBUG_PRINT_CHAN_VAL("Stereo L",
5367 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_LR_AMS_FMS, ch)]) & 0x80) >> 7);
5368 DEBUG_PRINT_CHAN_VAL("Stereo R",
5369 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_LR_AMS_FMS, ch)]) & 0x40) >> 6);
5370 DEBUG_PRINT_CHAN_VAL("AM Sensitivity",
5371 ((regs[debug_get_chan_reg_addr(YMREG_CHAN_LR_AMS_FMS, ch)]) & 0x30) >> 4);
5372 DEBUG_PRINT_CHAN_VAL("FM Sensitivity",
5373 (regs[debug_get_chan_reg_addr(YMREG_CHAN_LR_AMS_FMS, ch)]) & 0x7);
5376 for (op = 1; op <= DEBUG_MAX_OPS; op++)
5377 debug_show_ym2612_operator_regs(regs, ch, op);
5380 #define DEBUG_MAX_CHAN 6
5381 void debug_show_ym2612_regs()
5383 uint8_t regs[512], chan;
5385 YM2612_dump(0, regs);
5387 printf("ym2612:\n");
5388 debug_show_ym2612_global_regs(regs);
5390 for (chan = 1; chan <= DEBUG_MAX_CHAN; chan ++)
5391 debug_show_ym2612_chan_regs(regs, chan);
5393 #endif
5395 #endif /* BUILD_YM2612 */