3 ** File: fmopl.c - software implementation of FM sound generator
\r
4 ** types OPL and OPL2
\r
6 ** Copyright Jarek Burczynski (bujar at mame dot net)
\r
7 ** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development
\r
14 04-08-2003 Jarek Burczynski:
\r
15 - removed BFRDY hack. BFRDY is busy flag, and it should be 0 only when the chip
\r
16 handles memory read/write or during the adpcm synthesis when the chip
\r
17 requests another byte of ADPCM data.
\r
19 24-07-2003 Jarek Burczynski:
\r
20 - added a small hack for Y8950 status BFRDY flag (bit 3 should be set after
\r
21 some (unknown) delay). Right now it's always set.
\r
23 14-06-2003 Jarek Burczynski:
\r
24 - implemented all of the status register flags in Y8950 emulation
\r
25 - renamed y8950_set_delta_t_memory() parameters from _rom_ to _mem_ since
\r
26 they can be either RAM or ROM
\r
28 08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip)
\r
29 - corrected ym3526_read() to always set bit 2 and bit 1
\r
30 to HIGH state - identical to ym3812_read (verified on real YM3526)
\r
32 04-28-2002 Jarek Burczynski:
\r
33 - binary exact Envelope Generator (verified on real YM3812);
\r
34 compared to YM2151: the EG clock is equal to internal_clock,
\r
35 rates are 2 times slower and volume resolution is one bit less
\r
36 - modified interface functions (they no longer return pointer -
\r
37 that's internal to the emulator now):
\r
38 - new wrapper functions for OPLCreate: ym3526_init(), ym3812_init() and y8950_init()
\r
39 - corrected 'off by one' error in feedback calculations (when feedback is off)
\r
40 - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22)
\r
41 - speeded up noise generator calculations (Nicola Salmoria)
\r
43 03-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip)
\r
44 Complete rewrite (all verified on real YM3812):
\r
45 - corrected sin_tab and tl_tab data
\r
46 - corrected operator output calculations
\r
47 - corrected waveform_select_enable register;
\r
48 simply: ignore all writes to waveform_select register when
\r
49 waveform_select_enable == 0 and do not change the waveform previously selected.
\r
50 - corrected KSR handling
\r
51 - corrected Envelope Generator: attack shape, Sustain mode and
\r
52 Percussive/Non-percussive modes handling
\r
53 - Envelope Generator rates are two times slower now
\r
54 - LFO amplitude (tremolo) and phase modulation (vibrato)
\r
55 - rhythm sounds phase generation
\r
56 - white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm)
\r
57 - corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM)
\r
58 - funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1)
\r
60 12-28-2001 Acho A. Tang
\r
61 - reflected Delta-T EOS status on Y8950 status port.
\r
62 - fixed subscription range of attack/decay tables
\r
66 add delay before key off in CSM mode (see CSMKeyControll)
\r
67 verify volume of the FM part on the Y8950
\r
71 #include "mamedef.h"
\r
77 //#include "sndintrf.h"
\r
80 #include "ymdeltat.h"
\r
84 #define NULL ((void *)0)
\r
87 /* output final shift */
\r
88 #if (OPL_SAMPLE_BITS==16)
\r
89 #define FINAL_SH (0)
\r
90 #define MAXOUT (+32767)
\r
91 #define MINOUT (-32768)
\r
93 #define FINAL_SH (8)
\r
94 #define MAXOUT (+127)
\r
95 #define MINOUT (-128)
\r
99 #define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
\r
100 #define EG_SH 16 /* 16.16 fixed point (EG timing) */
\r
101 #define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
\r
102 #define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
\r
104 #define FREQ_MASK ((1<<FREQ_SH)-1)
\r
106 /* envelope output entries */
\r
107 #define ENV_BITS 10
\r
108 #define ENV_LEN (1<<ENV_BITS)
\r
109 #define ENV_STEP (128.0/ENV_LEN)
\r
111 #define MAX_ATT_INDEX ((1<<(ENV_BITS-1))-1) /*511*/
\r
112 #define MIN_ATT_INDEX (0)
\r
114 /* sinwave entries */
\r
115 #define SIN_BITS 10
\r
116 #define SIN_LEN (1<<SIN_BITS)
\r
117 #define SIN_MASK (SIN_LEN-1)
\r
119 #define TL_RES_LEN (256) /* 8 bits addressing (real chip) */
\r
123 /* register number to channel number , slot offset */
\r
127 /* Envelope Generator phases */
\r
136 /* save output as raw 16-bit sample */
\r
138 /*#define SAVE_SAMPLE*/
\r
141 INLINE signed int acc_calc(signed int value)
\r
145 if (value < 0x0200)
\r
146 return (value & ~0);
\r
147 if (value < 0x0400)
\r
148 return (value & ~1);
\r
149 if (value < 0x0800)
\r
150 return (value & ~3);
\r
151 if (value < 0x1000)
\r
152 return (value & ~7);
\r
153 if (value < 0x2000)
\r
154 return (value & ~15);
\r
155 if (value < 0x4000)
\r
156 return (value & ~31);
\r
157 return (value & ~63);
\r
160 if (value > -0x0200)
\r
161 return (~abs(value) & ~0);
\r
162 if (value > -0x0400)
\r
163 return (~abs(value) & ~1);
\r
164 if (value > -0x0800)
\r
165 return (~abs(value) & ~3);
\r
166 if (value > -0x1000)
\r
167 return (~abs(value) & ~7);
\r
168 if (value > -0x2000)
\r
169 return (~abs(value) & ~15);
\r
170 if (value > -0x4000)
\r
171 return (~abs(value) & ~31);
\r
172 return (~abs(value) & ~63);
\r
176 static FILE *sample[1];
\r
177 #if 1 /*save to MONO file */
\r
178 #define SAVE_ALL_CHANNELS \
\r
179 { signed int pom = acc_calc(lt); \
\r
180 fputc((unsigned short)pom&0xff,sample[0]); \
\r
181 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
\r
183 #else /*save to STEREO file */
\r
184 #define SAVE_ALL_CHANNELS \
\r
185 { signed int pom = lt; \
\r
186 fputc((unsigned short)pom&0xff,sample[0]); \
\r
187 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
\r
189 fputc((unsigned short)pom&0xff,sample[0]); \
\r
190 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
\r
195 //#define LOG_CYM_FILE 0
\r
196 //static FILE * cymfile = NULL;
\r
200 #define OPL_TYPE_WAVESEL 0x01 /* waveform select */
\r
201 #define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */
\r
202 #define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */
\r
203 #define OPL_TYPE_IO 0x08 /* I/O port */
\r
205 /* ---------- Generic interface section ---------- */
\r
206 #define OPL_TYPE_YM3526 (0)
\r
207 #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
\r
208 #define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
\r
214 UINT32 ar; /* attack rate: AR<<2 */
\r
215 UINT32 dr; /* decay rate: DR<<2 */
\r
216 UINT32 rr; /* release rate:RR<<2 */
\r
217 UINT8 KSR; /* key scale rate */
\r
218 UINT8 ksl; /* keyscale level */
\r
219 UINT8 ksr; /* key scale rate: kcode>>KSR */
\r
220 UINT8 mul; /* multiple: mul_tab[ML] */
\r
222 /* Phase Generator */
\r
223 UINT32 Cnt; /* frequency counter */
\r
224 UINT32 Incr; /* frequency counter step */
\r
225 UINT8 FB; /* feedback shift value */
\r
226 INT32 *connect1; /* slot1 output pointer */
\r
227 INT32 op1_out[2]; /* slot1 output for feedback */
\r
228 UINT8 CON; /* connection (algorithm) type */
\r
230 /* Envelope Generator */
\r
231 UINT8 eg_type; /* percussive/non-percussive mode */
\r
232 UINT8 state; /* phase type */
\r
233 UINT32 TL; /* total level: TL << 2 */
\r
234 INT32 TLL; /* adjusted now TL */
\r
235 INT32 volume; /* envelope counter */
\r
236 UINT32 sl; /* sustain level: sl_tab[SL] */
\r
237 UINT8 eg_sh_ar; /* (attack state) */
\r
238 UINT8 eg_sel_ar; /* (attack state) */
\r
239 UINT8 eg_sh_dr; /* (decay state) */
\r
240 UINT8 eg_sel_dr; /* (decay state) */
\r
241 UINT8 eg_sh_rr; /* (release state) */
\r
242 UINT8 eg_sel_rr; /* (release state) */
\r
243 UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */
\r
246 UINT32 AMmask; /* LFO Amplitude Modulation enable mask */
\r
247 UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/
\r
249 /* waveform select */
\r
256 /* phase generator state */
\r
257 UINT32 block_fnum; /* block+fnum */
\r
258 UINT32 fc; /* Freq. Increment base */
\r
259 UINT32 ksl_base; /* KeyScaleLevel Base step */
\r
260 UINT8 kcode; /* key code (for key scaling) */
\r
265 typedef struct fm_opl_f
\r
267 /* FM channel slots */
\r
268 OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/
\r
269 UINT8 MuteSpc[6]; /* Mute Special: 5 Rhythm + 1 DELTA-T Channel */
\r
271 UINT32 eg_cnt; /* global envelope generator counter */
\r
272 UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */
\r
273 UINT32 eg_timer_add; /* step of eg_timer */
\r
274 UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */
\r
276 UINT8 rhythm; /* Rhythm mode */
\r
278 UINT32 fn_tab[1024]; /* fnumber->increment counter */
\r
284 UINT8 lfo_am_depth;
\r
285 UINT8 lfo_pm_depth_range;
\r
291 UINT32 noise_rng; /* 23 bit noise shift register */
\r
292 UINT32 noise_p; /* current noise 'phase' */
\r
293 UINT32 noise_f; /* current noise period */
\r
295 UINT8 wavesel; /* waveform select enable flag */
\r
297 UINT32 T[2]; /* timer counters */
\r
299 UINT8 st[2]; /* timer enable */
\r
302 /* Delta-T ADPCM unit (Y8950) */
\r
306 /* Keyboard and I/O ports interface */
\r
307 UINT8 portDirection;
\r
309 OPL_PORTHANDLER_R porthandler_r;
\r
310 OPL_PORTHANDLER_W porthandler_w;
\r
312 OPL_PORTHANDLER_R keyboardhandler_r;
\r
313 OPL_PORTHANDLER_W keyboardhandler_w;
\r
314 void * keyboard_param;
\r
317 /* external event callback handlers */
\r
318 OPL_TIMERHANDLER timer_handler; /* TIMER handler */
\r
319 void *TimerParam; /* TIMER parameter */
\r
320 OPL_IRQHANDLER IRQHandler; /* IRQ handler */
\r
321 void *IRQParam; /* IRQ parameter */
\r
322 OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */
\r
323 void *UpdateParam; /* stream update parameter */
\r
325 UINT8 type; /* chip type */
\r
326 UINT8 address; /* address register */
\r
327 UINT8 status; /* status flag */
\r
328 UINT8 statusmask; /* status mask */
\r
329 UINT8 mode; /* Reg.08 : CSM,notesel,etc. */
\r
331 UINT32 clock; /* master clock (Hz) */
\r
332 UINT32 rate; /* sampling rate (Hz) */
\r
333 double freqbase; /* frequency base */
\r
334 //attotime TimerBase; /* Timer base time (==sampling time)*/
\r
336 signed int phase_modulation; /* phase modulation input (SLOT 2) */
\r
337 signed int output[1];
\r
339 INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */
\r
345 /* mapping of register number (offset) to slot number used by the emulator */
\r
346 static const int slot_array[32]=
\r
348 0, 2, 4, 1, 3, 5,-1,-1,
\r
349 6, 8,10, 7, 9,11,-1,-1,
\r
350 12,14,16,13,15,17,-1,-1,
\r
351 -1,-1,-1,-1,-1,-1,-1,-1
\r
354 /* key scale level */
\r
355 /* table is 3dB/octave , DV converts this into 6dB/octave */
\r
356 /* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */
\r
357 #define DV (0.1875/2.0)
\r
358 static const UINT32 ksl_tab[8*16]=
\r
361 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
362 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
363 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
364 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
366 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
367 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
368 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
\r
369 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
\r
371 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
\r
372 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
\r
373 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
\r
374 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
\r
376 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
\r
377 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
\r
378 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
\r
379 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
\r
381 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
\r
382 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
\r
383 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
\r
384 10.875/DV,11.250/DV,11.625/DV,12.000/DV,
\r
386 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
\r
387 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
\r
388 12.000/DV,12.750/DV,13.125/DV,13.500/DV,
\r
389 13.875/DV,14.250/DV,14.625/DV,15.000/DV,
\r
391 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
\r
392 12.000/DV,13.125/DV,13.875/DV,14.625/DV,
\r
393 15.000/DV,15.750/DV,16.125/DV,16.500/DV,
\r
394 16.875/DV,17.250/DV,17.625/DV,18.000/DV,
\r
396 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
\r
397 15.000/DV,16.125/DV,16.875/DV,17.625/DV,
\r
398 18.000/DV,18.750/DV,19.125/DV,19.500/DV,
\r
399 19.875/DV,20.250/DV,20.625/DV,21.000/DV
\r
403 /* 0 / 3.0 / 1.5 / 6.0 dB/OCT */
\r
404 static const UINT32 ksl_shift[4] = { 31, 1, 2, 0 };
\r
407 /* sustain level table (3dB per step) */
\r
408 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
\r
409 #define SC(db) (UINT32) ( db * (2.0/ENV_STEP) )
\r
410 static const UINT32 sl_tab[16]={
\r
411 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
\r
412 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
\r
417 #define RATE_STEPS (8)
\r
418 static const unsigned char eg_inc[15*RATE_STEPS]={
\r
420 /*cycle:0 1 2 3 4 5 6 7*/
\r
422 /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */
\r
423 /* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */
\r
424 /* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */
\r
425 /* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */
\r
427 /* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */
\r
428 /* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */
\r
429 /* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */
\r
430 /* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */
\r
432 /* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */
\r
433 /* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */
\r
434 /*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */
\r
435 /*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */
\r
437 /*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */
\r
438 /*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */
\r
439 /*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
\r
443 #define O(a) (a*RATE_STEPS)
\r
445 /*note that there is no O(13) in this table - it's directly in the code */
\r
446 static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */
\r
447 /* 16 infinite time rates */
\r
448 O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
\r
449 O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
\r
452 O( 0),O( 1),O( 2),O( 3),
\r
453 O( 0),O( 1),O( 2),O( 3),
\r
454 O( 0),O( 1),O( 2),O( 3),
\r
455 O( 0),O( 1),O( 2),O( 3),
\r
456 O( 0),O( 1),O( 2),O( 3),
\r
457 O( 0),O( 1),O( 2),O( 3),
\r
458 O( 0),O( 1),O( 2),O( 3),
\r
459 O( 0),O( 1),O( 2),O( 3),
\r
460 O( 0),O( 1),O( 2),O( 3),
\r
461 O( 0),O( 1),O( 2),O( 3),
\r
462 O( 0),O( 1),O( 2),O( 3),
\r
463 O( 0),O( 1),O( 2),O( 3),
\r
464 O( 0),O( 1),O( 2),O( 3),
\r
467 O( 4),O( 5),O( 6),O( 7),
\r
470 O( 8),O( 9),O(10),O(11),
\r
473 O(12),O(12),O(12),O(12),
\r
475 /* 16 dummy rates (same as 15 3) */
\r
476 O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
\r
477 O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
\r
482 /*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
\r
483 /*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */
\r
484 /*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */
\r
487 static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */
\r
488 /* 16 infinite time rates */
\r
489 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
\r
490 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
\r
493 O(12),O(12),O(12),O(12),
\r
494 O(11),O(11),O(11),O(11),
\r
495 O(10),O(10),O(10),O(10),
\r
496 O( 9),O( 9),O( 9),O( 9),
\r
497 O( 8),O( 8),O( 8),O( 8),
\r
498 O( 7),O( 7),O( 7),O( 7),
\r
499 O( 6),O( 6),O( 6),O( 6),
\r
500 O( 5),O( 5),O( 5),O( 5),
\r
501 O( 4),O( 4),O( 4),O( 4),
\r
502 O( 3),O( 3),O( 3),O( 3),
\r
503 O( 2),O( 2),O( 2),O( 2),
\r
504 O( 1),O( 1),O( 1),O( 1),
\r
505 O( 0),O( 0),O( 0),O( 0),
\r
508 O( 0),O( 0),O( 0),O( 0),
\r
511 O( 0),O( 0),O( 0),O( 0),
\r
514 O( 0),O( 0),O( 0),O( 0),
\r
516 /* 16 dummy rates (same as 15 3) */
\r
517 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
\r
518 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
\r
524 /* multiple table */
\r
526 static const UINT8 mul_tab[16]= {
\r
527 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */
\r
528 0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
\r
529 8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
\r
533 /* TL_TAB_LEN is calculated as:
\r
534 * 12 - sinus amplitude bits (Y axis)
\r
535 * 2 - sinus sign bit (Y axis)
\r
536 * TL_RES_LEN - sinus resolution (X axis)
\r
538 #define TL_TAB_LEN (12*2*TL_RES_LEN)
\r
539 static signed int tl_tab[TL_TAB_LEN];
\r
541 #define ENV_QUIET (TL_TAB_LEN>>4)
\r
543 /* sin waveform table in 'decibel' scale */
\r
544 /* four waveforms on OPL2 type chips */
\r
545 static unsigned int sin_tab[SIN_LEN * 4];
\r
548 /* LFO Amplitude Modulation table (verified on real YM3812)
\r
549 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples
\r
551 Length: 210 elements.
\r
553 Each of the elements has to be repeated
\r
554 exactly 64 times (on 64 consecutive samples).
\r
555 The whole table takes: 64 * 210 = 13440 samples.
\r
557 When AM = 1 data is used directly
\r
558 When AM = 0 data is divided by 4 before being used (losing precision is important)
\r
561 #define LFO_AM_TAB_ELEMENTS 210
\r
563 static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = {
\r
618 /* LFO Phase Modulation table (verified on real YM3812) */
\r
619 static const INT8 lfo_pm_table[8*8*2] = {
\r
621 /* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */
\r
622 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
\r
623 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/
\r
625 /* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */
\r
626 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
\r
627 1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/
\r
629 /* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */
\r
630 1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/
\r
631 2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/
\r
633 /* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */
\r
634 1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/
\r
635 3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/
\r
637 /* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */
\r
638 2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/
\r
639 4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/
\r
641 /* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */
\r
642 2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/
\r
643 5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/
\r
645 /* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */
\r
646 3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/
\r
647 6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/
\r
649 /* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */
\r
650 3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/
\r
651 7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/
\r
655 /* lock level of common table */
\r
656 static int num_lock = 0;
\r
659 #define SLOT7_1 (&OPL->P_CH[7].SLOT[SLOT1])
\r
660 #define SLOT7_2 (&OPL->P_CH[7].SLOT[SLOT2])
\r
661 #define SLOT8_1 (&OPL->P_CH[8].SLOT[SLOT1])
\r
662 #define SLOT8_2 (&OPL->P_CH[8].SLOT[SLOT2])
\r
667 /*INLINE int limit( int val, int max, int min ) {
\r
670 else if ( val < min )
\r
677 /* status set and IRQ handling */
\r
678 INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
\r
680 /* set status flag */
\r
681 OPL->status |= flag;
\r
682 if(!(OPL->status & 0x80))
\r
684 if(OPL->status & OPL->statusmask)
\r
686 OPL->status |= 0x80;
\r
687 /* callback user interrupt handler (IRQ is OFF to ON) */
\r
688 if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
\r
693 /* status reset and IRQ handling */
\r
694 INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
\r
696 /* reset status flag */
\r
697 OPL->status &=~flag;
\r
698 if((OPL->status & 0x80))
\r
700 if (!(OPL->status & OPL->statusmask) )
\r
702 OPL->status &= 0x7f;
\r
703 /* callback user interrupt handler (IRQ is ON to OFF) */
\r
704 if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
\r
710 INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
\r
712 OPL->statusmask = flag;
\r
713 /* IRQ handling check */
\r
714 OPL_STATUS_SET(OPL,0);
\r
715 OPL_STATUS_RESET(OPL,0);
\r
719 /* advance LFO to next sample */
\r
720 INLINE void advance_lfo(FM_OPL *OPL)
\r
725 OPL->lfo_am_cnt += OPL->lfo_am_inc;
\r
726 if (OPL->lfo_am_cnt >= ((UINT32)LFO_AM_TAB_ELEMENTS<<LFO_SH) ) /* lfo_am_table is 210 elements long */
\r
727 OPL->lfo_am_cnt -= ((UINT32)LFO_AM_TAB_ELEMENTS<<LFO_SH);
\r
729 tmp = lfo_am_table[ OPL->lfo_am_cnt >> LFO_SH ];
\r
731 if (OPL->lfo_am_depth)
\r
734 OPL->LFO_AM = tmp>>2;
\r
736 OPL->lfo_pm_cnt += OPL->lfo_pm_inc;
\r
737 OPL->LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range;
\r
740 INLINE void refresh_eg(FM_OPL* OPL)
\r
747 for (i=0; i<9*2; i++)
\r
749 CH = &OPL->P_CH[i/2];
\r
750 op = &CH->SLOT[i&1];
\r
752 // Envelope Generator
\r
755 case EG_ATT: // attack phase
\r
756 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_ar)-1) ) )
\r
758 new_vol = op->volume + ((~op->volume *
\r
759 (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)])
\r
761 if (new_vol <= MIN_ATT_INDEX)
\r
763 op->volume = MIN_ATT_INDEX;
\r
764 op->state = EG_DEC;
\r
768 /*case EG_DEC: // decay phase
\r
769 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_dr)-1) ) )
\r
771 new_vol = op->volume + eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)];
\r
773 if ( new_vol >= op->sl )
\r
774 op->state = EG_SUS;
\r
777 case EG_SUS: // sustain phase
\r
778 if ( !op->eg_type) percussive mode
\r
780 new_vol = op->volume + eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
\r
782 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
\r
784 if ( new_vol >= MAX_ATT_INDEX )
\r
785 op->volume = MAX_ATT_INDEX;
\r
789 case EG_REL: // release phase
\r
790 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
\r
792 new_vol = op->volume + eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
\r
793 if ( new_vol >= MAX_ATT_INDEX )
\r
795 op->volume = MAX_ATT_INDEX;
\r
796 op->state = EG_OFF;
\r
809 /* advance to next sample */
\r
810 INLINE void advance(FM_OPL *OPL)
\r
816 OPL->eg_timer += OPL->eg_timer_add;
\r
818 while (OPL->eg_timer >= OPL->eg_timer_overflow)
\r
820 OPL->eg_timer -= OPL->eg_timer_overflow;
\r
824 for (i = 0; i < 2; i ++)
\r
828 if (! OPL->Trem[i])
\r
829 OPLTimerOver(OPL, i);
\r
834 for (i=0; i<9*2; i++)
\r
836 CH = &OPL->P_CH[i/2];
\r
837 op = &CH->SLOT[i&1];
\r
839 /* Envelope Generator */
\r
842 case EG_ATT: /* attack phase */
\r
843 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_ar)-1) ) )
\r
845 op->volume += (~op->volume *
\r
846 (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)])
\r
849 if (op->volume <= MIN_ATT_INDEX)
\r
851 op->volume = MIN_ATT_INDEX;
\r
852 op->state = EG_DEC;
\r
858 case EG_DEC: /* decay phase */
\r
859 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_dr)-1) ) )
\r
861 op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)];
\r
863 if ( op->volume >= op->sl )
\r
864 op->state = EG_SUS;
\r
869 case EG_SUS: /* sustain phase */
\r
871 /* this is important behaviour:
\r
872 one can change percusive/non-percussive modes on the fly and
\r
873 the chip will remain in sustain phase - verified on real YM3812 */
\r
875 if(op->eg_type) /* non-percussive mode */
\r
879 else /* percussive mode */
\r
881 /* during sustain phase chip adds Release Rate (in percussive mode) */
\r
882 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
\r
884 op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
\r
886 if ( op->volume >= MAX_ATT_INDEX )
\r
887 op->volume = MAX_ATT_INDEX;
\r
889 /* else do nothing in sustain phase */
\r
893 case EG_REL: /* release phase */
\r
894 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
\r
896 op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
\r
898 if ( op->volume >= MAX_ATT_INDEX )
\r
900 op->volume = MAX_ATT_INDEX;
\r
901 op->state = EG_OFF;
\r
913 for (i=0; i<9*2; i++)
\r
915 CH = &OPL->P_CH[i/2];
\r
916 op = &CH->SLOT[i&1];
\r
918 /* Phase Generator */
\r
922 unsigned int block_fnum = CH->block_fnum;
\r
924 unsigned int fnum_lfo = (block_fnum&0x0380) >> 7;
\r
926 signed int lfo_fn_table_index_offset = lfo_pm_table[OPL->LFO_PM + 16*fnum_lfo ];
\r
928 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
\r
930 block_fnum += lfo_fn_table_index_offset;
\r
931 block = (block_fnum&0x1c00) >> 10;
\r
932 op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul;
\r
934 else /* LFO phase modulation = zero */
\r
936 op->Cnt += op->Incr;
\r
939 else /* LFO phase modulation disabled for this operator */
\r
941 op->Cnt += op->Incr;
\r
945 /* The Noise Generator of the YM3812 is 23-bit shift register.
\r
946 * Period is equal to 2^23-2 samples.
\r
947 * Register works at sampling frequency of the chip, so output
\r
948 * can change on every sample.
\r
950 * Output of the register and input to the bit 22 is:
\r
951 * bit0 XOR bit14 XOR bit15 XOR bit22
\r
953 * Simply use bit 22 as the noise output.
\r
956 OPL->noise_p += OPL->noise_f;
\r
957 i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */
\r
958 OPL->noise_p &= FREQ_MASK;
\r
963 j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1;
\r
964 OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1);
\r
968 Instead of doing all the logic operations above, we
\r
969 use a trick here (and use bit 0 as the noise output).
\r
970 The difference is only that the noise bit changes one
\r
971 step ahead. This doesn't matter since we don't know
\r
972 what is real state of the noise_rng after the reset.
\r
975 if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302;
\r
976 OPL->noise_rng >>= 1;
\r
983 INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab)
\r
987 p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ];
\r
989 if (p >= TL_TAB_LEN)
\r
994 INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab)
\r
998 p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ];
\r
1000 if (p >= TL_TAB_LEN)
\r
1006 #define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (OPL->LFO_AM & (OP)->AMmask))
\r
1008 /* calculate output */
\r
1009 INLINE void OPL_CALC_CH( FM_OPL *OPL, OPL_CH *CH )
\r
1018 OPL->phase_modulation = 0;
\r
1021 SLOT = &CH->SLOT[SLOT1];
\r
1022 env = volume_calc(SLOT);
\r
1023 out = SLOT->op1_out[0] + SLOT->op1_out[1];
\r
1024 SLOT->op1_out[0] = SLOT->op1_out[1];
\r
1025 *SLOT->connect1 += SLOT->op1_out[0];
\r
1026 SLOT->op1_out[1] = 0;
\r
1027 if( env < ENV_QUIET )
\r
1031 SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<<SLOT->FB), SLOT->wavetable );
\r
1036 env = volume_calc(SLOT);
\r
1037 if( env < ENV_QUIET )
\r
1038 OPL->output[0] += op_calc(SLOT->Cnt, env, OPL->phase_modulation, SLOT->wavetable);
\r
1042 operators used in the rhythm sounds generation process:
\r
1044 Envelope Generator:
\r
1046 channel operator register number Bass High Snare Tom Top
\r
1047 / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal
\r
1048 6 / 0 12 50 70 90 f0 +
\r
1049 6 / 1 15 53 73 93 f3 +
\r
1050 7 / 0 13 51 71 91 f1 +
\r
1051 7 / 1 16 54 74 94 f4 +
\r
1052 8 / 0 14 52 72 92 f2 +
\r
1053 8 / 1 17 55 75 95 f5 +
\r
1057 channel operator register number Bass High Snare Tom Top
\r
1058 / slot number MULTIPLE Drum Hat Drum Tom Cymbal
\r
1062 7 / 1 16 34 ----- n o t u s e d -----
\r
1066 channel operator register number Bass High Snare Tom Top
\r
1067 number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal
\r
1070 7 13,16 B7 A7 + + +
\r
1072 8 14,17 B8 A8 + + +
\r
1076 /* calculate rhythm */
\r
1078 INLINE void OPL_CALC_RH( FM_OPL *OPL, OPL_CH *CH, unsigned int noise )
\r
1085 /* Bass Drum (verified on real YM3812):
\r
1086 - depends on the channel 6 'connect' register:
\r
1087 when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out)
\r
1088 when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored
\r
1089 - output sample always is multiplied by 2
\r
1092 OPL->phase_modulation = 0;
\r
1094 SLOT = &CH[6].SLOT[SLOT1];
\r
1095 env = volume_calc(SLOT);
\r
1097 out = SLOT->op1_out[0] + SLOT->op1_out[1];
\r
1098 SLOT->op1_out[0] = SLOT->op1_out[1];
\r
1101 OPL->phase_modulation = SLOT->op1_out[0];
\r
1102 /* else ignore output of operator 1 */
\r
1104 SLOT->op1_out[1] = 0;
\r
1105 if( env < ENV_QUIET )
\r
1109 SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<<SLOT->FB), SLOT->wavetable );
\r
1114 env = volume_calc(SLOT);
\r
1115 if( env < ENV_QUIET && ! OPL->MuteSpc[0] )
\r
1116 OPL->output[0] += op_calc(SLOT->Cnt, env, OPL->phase_modulation, SLOT->wavetable) * 2;
\r
1119 /* Phase generation is based on: */
\r
1120 /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */
\r
1121 /* SD (16) channel 7->slot 1 */
\r
1122 /* TOM (14) channel 8->slot 1 */
\r
1123 /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */
\r
1125 /* Envelope generation based on: */
\r
1126 /* HH channel 7->slot1 */
\r
1127 /* SD channel 7->slot2 */
\r
1128 /* TOM channel 8->slot1 */
\r
1129 /* TOP channel 8->slot2 */
\r
1132 /* The following formulas can be well optimized.
\r
1133 I leave them in direct form for now (in case I've missed something).
\r
1136 /* High Hat (verified on real YM3812) */
\r
1137 env = volume_calc(SLOT7_1);
\r
1138 if( env < ENV_QUIET && ! OPL->MuteSpc[4] )
\r
1141 /* high hat phase generation:
\r
1142 phase = d0 or 234 (based on frequency only)
\r
1143 phase = 34 or 2d0 (based on noise)
\r
1146 /* base frequency derived from operator 1 in channel 7 */
\r
1147 unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1;
\r
1148 unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1;
\r
1149 unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1;
\r
1151 unsigned char res1 = (bit2 ^ bit7) | bit3;
\r
1153 /* when res1 = 0 phase = 0x000 | 0xd0; */
\r
1154 /* when res1 = 1 phase = 0x200 | (0xd0>>2); */
\r
1155 UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0;
\r
1157 /* enable gate based on frequency of operator 2 in channel 8 */
\r
1158 unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1;
\r
1159 unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1;
\r
1161 unsigned char res2 = (bit3e ^ bit5e);
\r
1163 /* when res2 = 0 pass the phase from calculation above (res1); */
\r
1164 /* when res2 = 1 phase = 0x200 | (0xd0>>2); */
\r
1166 phase = (0x200|(0xd0>>2));
\r
1169 /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
\r
1170 /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
\r
1174 phase = 0x200|0xd0;
\r
1177 /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */
\r
1178 /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */
\r
1184 OPL->output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
\r
1187 /* Snare Drum (verified on real YM3812) */
\r
1188 env = volume_calc(SLOT7_2);
\r
1189 if( env < ENV_QUIET && ! OPL->MuteSpc[1] )
\r
1191 /* base frequency derived from operator 1 in channel 7 */
\r
1192 unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1;
\r
1194 /* when bit8 = 0 phase = 0x100; */
\r
1195 /* when bit8 = 1 phase = 0x200; */
\r
1196 UINT32 phase = bit8 ? 0x200 : 0x100;
\r
1198 /* Noise bit XOR'es phase by 0x100 */
\r
1199 /* when noisebit = 0 pass the phase from calculation above */
\r
1200 /* when noisebit = 1 phase ^= 0x100; */
\r
1201 /* in other words: phase ^= (noisebit<<8); */
\r
1205 OPL->output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT7_2->wavetable) * 2;
\r
1208 /* Tom Tom (verified on real YM3812) */
\r
1209 env = volume_calc(SLOT8_1);
\r
1210 if( env < ENV_QUIET && ! OPL->MuteSpc[2] )
\r
1211 OPL->output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2;
\r
1213 /* Top Cymbal (verified on real YM3812) */
\r
1214 env = volume_calc(SLOT8_2);
\r
1215 if( env < ENV_QUIET && ! OPL->MuteSpc[3] )
\r
1217 /* base frequency derived from operator 1 in channel 7 */
\r
1218 unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1;
\r
1219 unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1;
\r
1220 unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1;
\r
1222 unsigned char res1 = (bit2 ^ bit7) | bit3;
\r
1224 /* when res1 = 0 phase = 0x000 | 0x100; */
\r
1225 /* when res1 = 1 phase = 0x200 | 0x100; */
\r
1226 UINT32 phase = res1 ? 0x300 : 0x100;
\r
1228 /* enable gate based on frequency of operator 2 in channel 8 */
\r
1229 unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1;
\r
1230 unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1;
\r
1232 unsigned char res2 = (bit3e ^ bit5e);
\r
1233 /* when res2 = 0 pass the phase from calculation above (res1); */
\r
1234 /* when res2 = 1 phase = 0x200 | 0x100; */
\r
1238 OPL->output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT8_2->wavetable) * 2;
\r
1243 /* generic table initialize */
\r
1244 static int init_tables(void)
\r
1251 for (x=0; x<TL_RES_LEN; x++)
\r
1253 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);
\r
1256 /* we never reach (1<<16) here due to the (x+1) */
\r
1257 /* result fits within 16 bits at maximum */
\r
1259 n = (int)m; /* 16 bits here */
\r
1260 n >>= 4; /* 12 bits here */
\r
1261 if (n&1) /* round to nearest */
\r
1265 /* 11 bits here (rounded) */
\r
1266 n <<= 1; /* 12 bits here (as in real chip) */
\r
1267 tl_tab[ x*2 + 0 ] = n;
\r
1268 tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ];
\r
1270 for (i=1; i<12; i++)
\r
1272 tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i;
\r
1273 tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ];
\r
1276 logerror("tl %04i", x*2);
\r
1277 for (i=0; i<12; i++)
\r
1278 logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] );
\r
1282 /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
\r
1285 for (i=0; i<SIN_LEN; i++)
\r
1287 /* non-standard sinus */
\r
1288 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */
\r
1290 /* we never reach zero here due to ((i*2)+1) */
\r
1293 o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */
\r
1295 o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */
\r
1297 o = o / (ENV_STEP/4);
\r
1300 if (n&1) /* round to nearest */
\r
1305 sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
\r
1307 /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/
\r
1310 for (i=0; i<SIN_LEN; i++)
\r
1312 /* waveform 1: __ __ */
\r
1313 /* / \____/ \____*/
\r
1314 /* output only first half of the sinus waveform (positive one) */
\r
1316 if (i & (1<<(SIN_BITS-1)) )
\r
1317 sin_tab[1*SIN_LEN+i] = TL_TAB_LEN;
\r
1319 sin_tab[1*SIN_LEN+i] = sin_tab[i];
\r
1321 /* waveform 2: __ __ __ __ */
\r
1325 sin_tab[2*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>1) ];
\r
1327 /* waveform 3: _ _ _ _ */
\r
1328 /* / |_/ |_/ |_/ |_*/
\r
1329 /* abs(output only first quarter of the sinus waveform) */
\r
1331 if (i & (1<<(SIN_BITS-2)) )
\r
1332 sin_tab[3*SIN_LEN+i] = TL_TAB_LEN;
\r
1334 sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)];
\r
1336 /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] );
\r
1337 logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] );
\r
1338 logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/
\r
1340 /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/
\r
1343 #ifdef SAVE_SAMPLE
\r
1344 sample[0]=fopen("sampsum.pcm","wb");
\r
1350 static void OPLCloseTable( void )
\r
1352 #ifdef SAVE_SAMPLE
\r
1353 fclose(sample[0]);
\r
1359 static void OPL_initalize(FM_OPL *OPL)
\r
1363 /* frequency base */
\r
1364 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0;
\r
1366 OPL->rate = (double)OPL->clock / 72.0;
\r
1367 OPL->freqbase = 1.0;
\r
1370 /*logerror("freqbase=%f\n", OPL->freqbase);*/
\r
1372 /* Timer base time */
\r
1373 //OPL->TimerBase = attotime_mul(ATTOTIME_IN_HZ(OPL->clock), 72);
\r
1375 /* make fnumber -> increment counter table */
\r
1376 for( i=0 ; i < 1024 ; i++ )
\r
1378 /* opn phase increment counter = 20bit */
\r
1379 OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
\r
1381 logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n",
\r
1382 i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 );
\r
1387 for( i=0 ; i < 16 ; i++ )
\r
1389 logerror("FMOPL.C: sl_tab[%i] = %08x\n",
\r
1392 for( i=0 ; i < 8 ; i++ )
\r
1395 logerror("FMOPL.C: ksl_tab[oct=%2i] =",i);
\r
1396 for (j=0; j<16; j++)
\r
1398 logerror("%08x ", ksl_tab[i*16+j] );
\r
1404 for(i = 0; i < 9; i ++)
\r
1405 OPL->P_CH[i].Muted = 0x00;
\r
1406 for(i = 0; i < 6; i ++)
\r
1407 OPL->MuteSpc[i] = 0x00;
\r
1410 /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */
\r
1411 /* One entry from LFO_AM_TABLE lasts for 64 samples */
\r
1412 OPL->lfo_am_inc = (1.0 / 64.0 ) * (1<<LFO_SH) * OPL->freqbase;
\r
1414 /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */
\r
1415 OPL->lfo_pm_inc = (1.0 / 1024.0) * (1<<LFO_SH) * OPL->freqbase;
\r
1417 /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/
\r
1419 /* Noise generator: a step takes 1 sample */
\r
1420 OPL->noise_f = (1.0 / 1.0) * (1<<FREQ_SH) * OPL->freqbase;
\r
1422 OPL->eg_timer_add = (1<<EG_SH) * OPL->freqbase;
\r
1423 OPL->eg_timer_overflow = ( 1 ) * (1<<EG_SH);
\r
1424 /*logerror("OPLinit eg_timer_add=%8x eg_timer_overflow=%8x\n", OPL->eg_timer_add, OPL->eg_timer_overflow);*/
\r
1428 INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set)
\r
1432 /* restart Phase Generator */
\r
1434 /* phase -> Attack */
\r
1435 SLOT->state = EG_ATT;
\r
1437 SLOT->key |= key_set;
\r
1440 INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr)
\r
1444 SLOT->key &= key_clr;
\r
1448 /* phase -> Release */
\r
1449 if (SLOT->state>EG_REL)
\r
1450 SLOT->state = EG_REL;
\r
1455 /* update phase increment counter of operator (also update the EG rates if necessary) */
\r
1456 INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
\r
1460 /* (frequency) phase increment counter */
\r
1461 SLOT->Incr = CH->fc * SLOT->mul;
\r
1462 ksr = CH->kcode >> SLOT->KSR;
\r
1464 if( SLOT->ksr != ksr )
\r
1468 /* calculate envelope generator rates */
\r
1469 if ((SLOT->ar + SLOT->ksr) < 16+62)
\r
1471 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
\r
1472 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
\r
1476 SLOT->eg_sh_ar = 0;
\r
1477 SLOT->eg_sel_ar = 13*RATE_STEPS;
\r
1479 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
\r
1480 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
\r
1481 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
\r
1482 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
\r
1486 /* set multi,am,vib,EG-TYP,KSR,mul */
\r
1487 INLINE void set_mul(FM_OPL *OPL,int slot,int v)
\r
1489 OPL_CH *CH = &OPL->P_CH[slot/2];
\r
1490 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
\r
1492 SLOT->mul = mul_tab[v&0x0f];
\r
1493 SLOT->KSR = (v&0x10) ? 0 : 2;
\r
1494 SLOT->eg_type = (v&0x20);
\r
1495 SLOT->vib = (v&0x40);
\r
1496 SLOT->AMmask = (v&0x80) ? ~0 : 0;
\r
1497 CALC_FCSLOT(CH,SLOT);
\r
1500 /* set ksl & tl */
\r
1501 INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
\r
1503 OPL_CH *CH = &OPL->P_CH[slot/2];
\r
1504 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
\r
1506 SLOT->ksl = ksl_shift[v >> 6];
\r
1507 SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */
\r
1509 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
\r
1512 /* set attack rate & decay rate */
\r
1513 INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
\r
1515 OPL_CH *CH = &OPL->P_CH[slot/2];
\r
1516 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
\r
1518 SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0;
\r
1520 if ((SLOT->ar + SLOT->ksr) < 16+62)
\r
1522 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
\r
1523 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
\r
1527 SLOT->eg_sh_ar = 0;
\r
1528 SLOT->eg_sel_ar = 13*RATE_STEPS;
\r
1531 SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
\r
1532 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
\r
1533 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
\r
1536 /* set sustain level & release rate */
\r
1537 INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
\r
1539 OPL_CH *CH = &OPL->P_CH[slot/2];
\r
1540 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
\r
1542 SLOT->sl = sl_tab[ v>>4 ];
\r
1544 SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
\r
1545 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
\r
1546 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
\r
1550 /* write a value v to register r on OPL chip */
\r
1551 static void OPLWriteReg(FM_OPL *OPL, int r, int v)
\r
1558 /* adjust bus to 8 bits */
\r
1562 /*if (LOG_CYM_FILE && (cymfile) && (r!=0) )
\r
1564 fputc( (unsigned char)r, cymfile );
\r
1565 fputc( (unsigned char)v, cymfile );
\r
1571 case 0x00: /* 00-1f:control */
\r
1574 case 0x01: /* waveform select enable */
\r
1575 if(OPL->type&OPL_TYPE_WAVESEL)
\r
1577 OPL->wavesel = v&0x20;
\r
1578 /* do not change the waveform previously selected */
\r
1581 case 0x02: /* Timer 1 */
\r
1582 OPL->T[0] = (256-v)*4;
\r
1584 case 0x03: /* Timer 2 */
\r
1585 OPL->T[1] = (256-v)*16;
\r
1587 case 0x04: /* IRQ clear / mask and Timer enable */
\r
1589 { /* IRQ flag clear */
\r
1590 OPL_STATUS_RESET(OPL,0x7f-0x08); /* don't reset BFRDY flag or we will have to call deltat module to set the flag */
\r
1593 { /* set IRQ mask ,timer enable*/
\r
1595 UINT8 st2 = (v>>1)&1;
\r
1597 /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
\r
1598 OPL_STATUS_RESET(OPL, v & (0x78-0x08) );
\r
1599 OPL_STATUSMASK_SET(OPL, (~v) & 0x78 );
\r
1602 if(OPL->st[1] != st2)
\r
1604 //attotime period = st2 ? attotime_mul(OPL->TimerBase, OPL->T[1]) : attotime_zero;
\r
1606 //if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,1,period);
\r
1609 if(OPL->st[0] != st1)
\r
1611 //attotime period = st1 ? attotime_mul(OPL->TimerBase, OPL->T[0]) : attotime_zero;
\r
1613 //if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,0,period);
\r
1618 case 0x06: /* Key Board OUT */
\r
1619 if(OPL->type&OPL_TYPE_KEYBOARD)
\r
1621 if(OPL->keyboardhandler_w)
\r
1622 OPL->keyboardhandler_w(OPL->keyboard_param,v);
\r
1625 logerror("Y8950: write unmapped KEYBOARD port\n");
\r
1629 case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
\r
1630 if(OPL->type&OPL_TYPE_ADPCM)
\r
1631 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
\r
1634 case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
\r
1637 if(OPL->type&OPL_TYPE_ADPCM)
\r
1638 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */
\r
1643 case 0x09: /* START ADD */
\r
1645 case 0x0b: /* STOP ADD */
\r
1647 case 0x0d: /* PRESCALE */
\r
1649 case 0x0f: /* ADPCM data write */
\r
1650 case 0x10: /* DELTA-N */
\r
1651 case 0x11: /* DELTA-N */
\r
1652 case 0x12: /* ADPCM volume */
\r
1653 if(OPL->type&OPL_TYPE_ADPCM)
\r
1654 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
\r
1657 case 0x15: /* DAC data high 8 bits (F7,F6...F2) */
\r
1658 case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */
\r
1659 case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */
\r
1661 logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v);
\r
1665 case 0x18: /* I/O CTRL (Direction) */
\r
1666 if(OPL->type&OPL_TYPE_IO)
\r
1667 OPL->portDirection = v&0x0f;
\r
1669 case 0x19: /* I/O DATA */
\r
1670 if(OPL->type&OPL_TYPE_IO)
\r
1672 OPL->portLatch = v;
\r
1673 if(OPL->porthandler_w)
\r
1674 OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
\r
1680 logerror("FMOPL.C: write to unknown register: %02x\n",r);
\r
1685 case 0x20: /* am ON, vib ON, ksr, eg_type, mul */
\r
1686 slot = slot_array[r&0x1f];
\r
1687 if(slot < 0) return;
\r
1688 set_mul(OPL,slot,v);
\r
1691 slot = slot_array[r&0x1f];
\r
1692 if(slot < 0) return;
\r
1693 set_ksl_tl(OPL,slot,v);
\r
1696 slot = slot_array[r&0x1f];
\r
1697 if(slot < 0) return;
\r
1698 set_ar_dr(OPL,slot,v);
\r
1701 slot = slot_array[r&0x1f];
\r
1702 if(slot < 0) return;
\r
1703 set_sl_rr(OPL,slot,v);
\r
1706 if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */
\r
1708 OPL->lfo_am_depth = v & 0x80;
\r
1709 OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0;
\r
1711 OPL->rhythm = v&0x3f;
\r
1713 if(OPL->rhythm&0x20)
\r
1715 /* BD key on/off */
\r
1718 FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2);
\r
1719 FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2);
\r
1723 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2);
\r
1724 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2);
\r
1726 /* HH key on/off */
\r
1727 if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2);
\r
1728 else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2);
\r
1729 /* SD key on/off */
\r
1730 if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2);
\r
1731 else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2);
\r
1732 /* TOM key on/off */
\r
1733 if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2);
\r
1734 else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2);
\r
1735 /* TOP-CY key on/off */
\r
1736 if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2);
\r
1737 else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2);
\r
1742 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2);
\r
1743 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2);
\r
1745 FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2);
\r
1747 FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2);
\r
1749 FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2);
\r
1751 FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2);
\r
1755 /* keyon,block,fnum */
\r
1756 if( (r&0x0f) > 8) return;
\r
1757 CH = &OPL->P_CH[r&0x0f];
\r
1760 block_fnum = (CH->block_fnum&0x1f00) | v;
\r
1764 block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
\r
1768 FM_KEYON (&CH->SLOT[SLOT1], 1);
\r
1769 FM_KEYON (&CH->SLOT[SLOT2], 1);
\r
1773 FM_KEYOFF(&CH->SLOT[SLOT1],~1);
\r
1774 FM_KEYOFF(&CH->SLOT[SLOT2],~1);
\r
1778 if(CH->block_fnum != block_fnum)
\r
1780 UINT8 block = block_fnum >> 10;
\r
1782 CH->block_fnum = block_fnum;
\r
1784 CH->ksl_base = ksl_tab[block_fnum>>6];
\r
1785 CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block);
\r
1787 /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */
\r
1788 CH->kcode = (CH->block_fnum&0x1c00)>>9;
\r
1790 /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */
\r
1791 /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */
\r
1792 /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */
\r
1793 if (OPL->mode&0x40)
\r
1794 CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */
\r
1796 CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */
\r
1798 /* refresh Total Level in both SLOTs of this channel */
\r
1799 CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl);
\r
1800 CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl);
\r
1802 /* refresh frequency counter in both SLOTs of this channel */
\r
1803 CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
\r
1804 CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
\r
1809 if( (r&0x0f) > 8) return;
\r
1810 CH = &OPL->P_CH[r&0x0f];
\r
1811 CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0;
\r
1812 CH->SLOT[SLOT1].CON = v&1;
\r
1813 CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &OPL->output[0] : &OPL->phase_modulation;
\r
1815 case 0xe0: /* waveform select */
\r
1816 /* simply ignore write to the waveform select register if selecting not enabled in test register */
\r
1819 slot = slot_array[r&0x1f];
\r
1820 if(slot < 0) return;
\r
1821 CH = &OPL->P_CH[slot/2];
\r
1823 CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN;
\r
1829 /*static TIMER_CALLBACK( cymfile_callback )
\r
1833 fputc( (unsigned char)0, cymfile );
\r
1837 /* lock/unlock for common table */
\r
1838 static int OPL_LockTable(void)
\r
1841 if(num_lock>1) return 0;
\r
1845 /* allocate total level table (128kb space) */
\r
1846 if( !init_tables() )
\r
1852 /*if (LOG_CYM_FILE)
\r
1854 cymfile = fopen("3812_.cym","wb");
\r
1856 timer_pulse ( device->machine, ATTOTIME_IN_HZ(110), NULL, 0, cymfile_callback); //110 Hz pulse timer
\r
1858 logerror("Could not create file 3812_.cym\n");
\r
1864 static void OPL_UnLockTable(void)
\r
1866 if(num_lock) num_lock--;
\r
1867 if(num_lock) return;
\r
1878 static void OPLResetChip(FM_OPL *OPL)
\r
1883 OPL->eg_timer = 0;
\r
1886 OPL->noise_rng = 1; /* noise shift register */
\r
1887 OPL->mode = 0; /* normal mode */
\r
1888 OPL_STATUS_RESET(OPL,0x7f);
\r
1890 /* reset with register write */
\r
1891 OPLWriteReg(OPL,0x01,0); /* wavesel disable */
\r
1892 OPLWriteReg(OPL,0x02,0); /* Timer1 */
\r
1893 OPLWriteReg(OPL,0x03,0); /* Timer2 */
\r
1894 OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
\r
1895 OPL->Trem[0] = OPL->Trem[1] = 0;
\r
1896 for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
\r
1898 /* reset operator parameters */
\r
1899 for( c = 0 ; c < 9 ; c++ )
\r
1901 OPL_CH *CH = &OPL->P_CH[c];
\r
1902 for(s = 0 ; s < 2 ; s++ )
\r
1905 CH->SLOT[s].wavetable = 0;
\r
1906 CH->SLOT[s].state = EG_OFF;
\r
1907 CH->SLOT[s].volume = MAX_ATT_INDEX;
\r
1911 if(OPL->type&OPL_TYPE_ADPCM)
\r
1913 YM_DELTAT *DELTAT = OPL->deltat;
\r
1915 DELTAT->freqbase = OPL->freqbase;
\r
1916 DELTAT->output_pointer = &OPL->output_deltat[0];
\r
1917 DELTAT->portshift = 5;
\r
1918 DELTAT->output_range = 1<<23;
\r
1919 YM_DELTAT_ADPCM_Reset(DELTAT,0,YM_DELTAT_EMULATION_MODE_NORMAL);
\r
1926 //static STATE_POSTLOAD( OPL_postload )
\r
1927 static void OPL_postload(void* param)
\r
1929 FM_OPL *OPL = (FM_OPL *)param;
\r
1932 for( ch=0 ; ch < 9 ; ch++ )
\r
1934 OPL_CH *CH = &OPL->P_CH[ch];
\r
1936 /* Look up key scale level */
\r
1937 UINT32 block_fnum = CH->block_fnum;
\r
1938 CH->ksl_base = ksl_tab[block_fnum >> 6];
\r
1939 CH->fc = OPL->fn_tab[block_fnum & 0x03ff] >> (7 - (block_fnum >> 10));
\r
1941 for( slot=0 ; slot < 2 ; slot++ )
\r
1943 OPL_SLOT *SLOT = &CH->SLOT[slot];
\r
1945 /* Calculate key scale rate */
\r
1946 SLOT->ksr = CH->kcode >> SLOT->KSR;
\r
1948 /* Calculate attack, decay and release rates */
\r
1949 if ((SLOT->ar + SLOT->ksr) < 16+62)
\r
1951 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
\r
1952 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
\r
1956 SLOT->eg_sh_ar = 0;
\r
1957 SLOT->eg_sel_ar = 13*RATE_STEPS;
\r
1959 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
\r
1960 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
\r
1961 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
\r
1962 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
\r
1964 /* Calculate phase increment */
\r
1965 SLOT->Incr = CH->fc * SLOT->mul;
\r
1968 SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
\r
1970 /* Connect output */
\r
1971 SLOT->connect1 = SLOT->CON ? &OPL->output[0] : &OPL->phase_modulation;
\r
1975 if ( (OPL->type & OPL_TYPE_ADPCM) && (OPL->deltat) )
\r
1977 // We really should call the postlod function for the YM_DELTAT, but it's hard without registers
\r
1978 // (see the way the YM2610 does it)
\r
1979 //YM_DELTAT_postload(OPL->deltat, REGS);
\r
1985 static void OPLsave_state_channel(OPL_CH *CH)
\r
1989 for( ch=0 ; ch < 9 ; ch++, CH++ )
\r
1992 state_save_register_device_item(device, ch, CH->block_fnum);
\r
1993 state_save_register_device_item(device, ch, CH->kcode);
\r
1995 for( slot=0 ; slot < 2 ; slot++ )
\r
1997 OPL_SLOT *SLOT = &CH->SLOT[slot];
\r
1999 state_save_register_device_item(device, ch * 2 + slot, SLOT->ar);
\r
2000 state_save_register_device_item(device, ch * 2 + slot, SLOT->dr);
\r
2001 state_save_register_device_item(device, ch * 2 + slot, SLOT->rr);
\r
2002 state_save_register_device_item(device, ch * 2 + slot, SLOT->KSR);
\r
2003 state_save_register_device_item(device, ch * 2 + slot, SLOT->ksl);
\r
2004 state_save_register_device_item(device, ch * 2 + slot, SLOT->mul);
\r
2006 state_save_register_device_item(device, ch * 2 + slot, SLOT->Cnt);
\r
2007 state_save_register_device_item(device, ch * 2 + slot, SLOT->FB);
\r
2008 state_save_register_device_item_array(device, ch * 2 + slot, SLOT->op1_out);
\r
2009 state_save_register_device_item(device, ch * 2 + slot, SLOT->CON);
\r
2011 state_save_register_device_item(device, ch * 2 + slot, SLOT->eg_type);
\r
2012 state_save_register_device_item(device, ch * 2 + slot, SLOT->state);
\r
2013 state_save_register_device_item(device, ch * 2 + slot, SLOT->TL);
\r
2014 state_save_register_device_item(device, ch * 2 + slot, SLOT->volume);
\r
2015 state_save_register_device_item(device, ch * 2 + slot, SLOT->sl);
\r
2016 state_save_register_device_item(device, ch * 2 + slot, SLOT->key);
\r
2018 state_save_register_device_item(device, ch * 2 + slot, SLOT->AMmask);
\r
2019 state_save_register_device_item(device, ch * 2 + slot, SLOT->vib);
\r
2021 state_save_register_device_item(device, ch * 2 + slot, SLOT->wavetable);
\r
2028 /* Register savestate for a virtual YM3812/YM3526/Y8950 */
\r
2030 /*static void OPL_save_state(FM_OPL *OPL)
\r
2032 OPLsave_state_channel(device, OPL->P_CH);
\r
2034 state_save_register_device_item(device, 0, OPL->eg_cnt);
\r
2035 state_save_register_device_item(device, 0, OPL->eg_timer);
\r
2037 state_save_register_device_item(device, 0, OPL->rhythm);
\r
2039 state_save_register_device_item(device, 0, OPL->lfo_am_depth);
\r
2040 state_save_register_device_item(device, 0, OPL->lfo_pm_depth_range);
\r
2041 state_save_register_device_item(device, 0, OPL->lfo_am_cnt);
\r
2042 state_save_register_device_item(device, 0, OPL->lfo_pm_cnt);
\r
2044 state_save_register_device_item(device, 0, OPL->noise_rng);
\r
2045 state_save_register_device_item(device, 0, OPL->noise_p);
\r
2047 if( OPL->type & OPL_TYPE_WAVESEL )
\r
2049 state_save_register_device_item(device, 0, OPL->wavesel);
\r
2052 state_save_register_device_item_array(device, 0, OPL->T);
\r
2053 state_save_register_device_item_array(device, 0, OPL->st);
\r
2056 if ( (OPL->type & OPL_TYPE_ADPCM) && (OPL->deltat) )
\r
2058 YM_DELTAT_savestate(device, OPL->deltat);
\r
2061 if ( OPL->type & OPL_TYPE_IO )
\r
2063 state_save_register_device_item(device, 0, OPL->portDirection);
\r
2064 state_save_register_device_item(device, 0, OPL->portLatch);
\r
2068 state_save_register_device_item(device, 0, OPL->address);
\r
2069 state_save_register_device_item(device, 0, OPL->status);
\r
2070 state_save_register_device_item(device, 0, OPL->statusmask);
\r
2071 state_save_register_device_item(device, 0, OPL->mode);
\r
2073 state_save_register_postload(device->machine, OPL_postload, OPL);
\r
2077 /* Create one of virtual YM3812/YM3526/Y8950 */
\r
2078 /* 'clock' is chip clock in Hz */
\r
2079 /* 'rate' is sampling rate */
\r
2080 static FM_OPL *OPLCreate(UINT32 clock, UINT32 rate, int type)
\r
2086 if (OPL_LockTable() == -1) return NULL;
\r
2088 /* calculate OPL state size */
\r
2089 state_size = sizeof(FM_OPL);
\r
2092 if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
\r
2095 /* allocate memory block */
\r
2096 ptr = (char *)malloc(state_size);
\r
2102 memset(ptr,0,state_size);
\r
2104 OPL = (FM_OPL *)ptr;
\r
2106 ptr += sizeof(FM_OPL);
\r
2109 if (type&OPL_TYPE_ADPCM)
\r
2111 OPL->deltat = (YM_DELTAT *)ptr;
\r
2113 ptr += sizeof(YM_DELTAT);
\r
2117 OPL->clock = clock;
\r
2120 /* init global tables */
\r
2121 OPL_initalize(OPL);
\r
2126 /* Destroy one of virtual YM3812 */
\r
2127 static void OPLDestroy(FM_OPL *OPL)
\r
2129 OPL_UnLockTable();
\r
2133 /* Optional handlers */
\r
2135 static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER timer_handler,void *param)
\r
2137 OPL->timer_handler = timer_handler;
\r
2138 OPL->TimerParam = param;
\r
2140 static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,void *param)
\r
2142 OPL->IRQHandler = IRQHandler;
\r
2143 OPL->IRQParam = param;
\r
2145 static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,void *param)
\r
2147 OPL->UpdateHandler = UpdateHandler;
\r
2148 OPL->UpdateParam = param;
\r
2151 static int OPLWrite(FM_OPL *OPL,int a,int v)
\r
2154 { /* address port */
\r
2155 OPL->address = v & 0xff;
\r
2159 if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam/*,0*/);
\r
2160 OPLWriteReg(OPL,OPL->address,v);
\r
2162 return OPL->status>>7;
\r
2165 static unsigned char OPLRead(FM_OPL *OPL,int a)
\r
2173 if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */
\r
2175 return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1);
\r
2180 /* OPL and OPL2 */
\r
2181 return OPL->status & (OPL->statusmask|0x80);
\r
2186 switch(OPL->address)
\r
2188 case 0x05: /* KeyBoard IN */
\r
2189 if(OPL->type&OPL_TYPE_KEYBOARD)
\r
2191 if(OPL->keyboardhandler_r)
\r
2192 return OPL->keyboardhandler_r(OPL->keyboard_param);
\r
2195 logerror("Y8950: read unmapped KEYBOARD port\n");
\r
2200 case 0x0f: /* ADPCM-DATA */
\r
2201 if(OPL->type&OPL_TYPE_ADPCM)
\r
2205 val = YM_DELTAT_ADPCM_Read(OPL->deltat);
\r
2206 /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/
\r
2211 case 0x19: /* I/O DATA */
\r
2212 if(OPL->type&OPL_TYPE_IO)
\r
2214 if(OPL->porthandler_r)
\r
2215 return OPL->porthandler_r(OPL->port_param);
\r
2218 logerror("Y8950:read unmapped I/O port\n");
\r
2222 case 0x1a: /* PCM-DATA */
\r
2223 if(OPL->type&OPL_TYPE_ADPCM)
\r
2226 logerror("Y8950 A/D convertion is accessed but not implemented !\n");
\r
2228 return 0x80; /* 2's complement PCM data - result from A/D convertion */
\r
2237 /* CSM Key Controll */
\r
2238 INLINE void CSMKeyControll(OPL_CH *CH)
\r
2240 FM_KEYON (&CH->SLOT[SLOT1], 4);
\r
2241 FM_KEYON (&CH->SLOT[SLOT2], 4);
\r
2243 /* The key off should happen exactly one sample later - not implemented correctly yet */
\r
2245 FM_KEYOFF(&CH->SLOT[SLOT1], ~4);
\r
2246 FM_KEYOFF(&CH->SLOT[SLOT2], ~4);
\r
2250 static int OPLTimerOver(FM_OPL *OPL,int c)
\r
2254 OPL_STATUS_SET(OPL,0x20);
\r
2258 OPL_STATUS_SET(OPL,0x40);
\r
2259 /* CSM mode key,TL controll */
\r
2260 if( OPL->mode & 0x80 )
\r
2261 { /* CSM mode total level latch and auto key on */
\r
2263 if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam/*,0*/);
\r
2264 for(ch=0; ch<9; ch++)
\r
2265 CSMKeyControll( &OPL->P_CH[ch] );
\r
2268 /* reload timer */
\r
2269 OPL->Trem[c] = OPL->T[c];
\r
2270 //if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,c,attotime_mul(OPL->TimerBase, OPL->T[c]));
\r
2271 return OPL->status>>7;
\r
2275 #define MAX_OPL_CHIPS 2
\r
2278 #if (BUILD_YM3812)
\r
2280 void * ym3812_init(UINT32 clock, UINT32 rate)
\r
2282 /* emulator create */
\r
2283 FM_OPL *YM3812 = OPLCreate(clock,rate,OPL_TYPE_YM3812);
\r
2286 //OPL_save_state(YM3812);
\r
2287 ym3812_reset_chip(YM3812);
\r
2292 void ym3812_shutdown(void *chip)
\r
2294 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2295 /* emulator shutdown */
\r
2296 OPLDestroy(YM3812);
\r
2298 void ym3812_reset_chip(void *chip)
\r
2300 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2301 OPLResetChip(YM3812);
\r
2304 int ym3812_write(void *chip, int a, int v)
\r
2306 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2307 return OPLWrite(YM3812, a, v);
\r
2310 unsigned char ym3812_read(void *chip, int a)
\r
2312 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2313 /* YM3812 always returns bit2 and bit1 in HIGH state */
\r
2314 return OPLRead(YM3812, a) | 0x06 ;
\r
2316 int ym3812_timer_over(void *chip, int c)
\r
2318 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2319 return OPLTimerOver(YM3812, c);
\r
2322 void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param)
\r
2324 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2325 OPLSetTimerHandler(YM3812, timer_handler, param);
\r
2327 void ym3812_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param)
\r
2329 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2330 OPLSetIRQHandler(YM3812, IRQHandler, param);
\r
2332 void ym3812_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param)
\r
2334 FM_OPL *YM3812 = (FM_OPL *)chip;
\r
2335 OPLSetUpdateHandler(YM3812, UpdateHandler, param);
\r
2340 ** Generate samples for one of the YM3812's
\r
2342 ** 'which' is the virtual YM3812 number
\r
2343 ** '*buffer' is the output buffer pointer
\r
2344 ** 'length' is the number of samples that should be generated
\r
2346 void ym3812_update_one(void *chip, OPLSAMPLE **buffer, int length)
\r
2348 FM_OPL *OPL = (FM_OPL *)chip;
\r
2349 UINT8 rhythm = OPL->rhythm&0x20;
\r
2350 OPLSAMPLE *bufL = buffer[0];
\r
2351 OPLSAMPLE *bufR = buffer[1];
\r
2360 for( i=0; i < length ; i++ )
\r
2364 OPL->output[0] = 0;
\r
2369 OPL_CALC_CH(OPL, &OPL->P_CH[0]);
\r
2370 OPL_CALC_CH(OPL, &OPL->P_CH[1]);
\r
2371 OPL_CALC_CH(OPL, &OPL->P_CH[2]);
\r
2372 OPL_CALC_CH(OPL, &OPL->P_CH[3]);
\r
2373 OPL_CALC_CH(OPL, &OPL->P_CH[4]);
\r
2374 OPL_CALC_CH(OPL, &OPL->P_CH[5]);
\r
2378 OPL_CALC_CH(OPL, &OPL->P_CH[6]);
\r
2379 OPL_CALC_CH(OPL, &OPL->P_CH[7]);
\r
2380 OPL_CALC_CH(OPL, &OPL->P_CH[8]);
\r
2382 else /* Rhythm part */
\r
2384 OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
\r
2387 lt = OPL->output[0];
\r
2392 //lt = limit( lt , MAXOUT, MINOUT );
\r
2394 #ifdef SAVE_SAMPLE
\r
2401 /* store to sound buffer */
\r
2409 #endif /* BUILD_YM3812 */
\r
2413 #if (BUILD_YM3526)
\r
2415 void *ym3526_init(UINT32 clock, UINT32 rate)
\r
2417 /* emulator create */
\r
2418 FM_OPL *YM3526 = OPLCreate(clock,rate,OPL_TYPE_YM3526);
\r
2421 //OPL_save_state(YM3526);
\r
2422 ym3526_reset_chip(YM3526);
\r
2427 void ym3526_shutdown(void *chip)
\r
2429 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2430 /* emulator shutdown */
\r
2431 OPLDestroy(YM3526);
\r
2433 void ym3526_reset_chip(void *chip)
\r
2435 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2436 OPLResetChip(YM3526);
\r
2439 int ym3526_write(void *chip, int a, int v)
\r
2441 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2442 return OPLWrite(YM3526, a, v);
\r
2445 unsigned char ym3526_read(void *chip, int a)
\r
2447 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2448 /* YM3526 always returns bit2 and bit1 in HIGH state */
\r
2449 return OPLRead(YM3526, a) | 0x06 ;
\r
2451 int ym3526_timer_over(void *chip, int c)
\r
2453 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2454 return OPLTimerOver(YM3526, c);
\r
2457 void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param)
\r
2459 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2460 OPLSetTimerHandler(YM3526, timer_handler, param);
\r
2462 void ym3526_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param)
\r
2464 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2465 OPLSetIRQHandler(YM3526, IRQHandler, param);
\r
2467 void ym3526_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param)
\r
2469 FM_OPL *YM3526 = (FM_OPL *)chip;
\r
2470 OPLSetUpdateHandler(YM3526, UpdateHandler, param);
\r
2475 ** Generate samples for one of the YM3526's
\r
2477 ** 'which' is the virtual YM3526 number
\r
2478 ** '*buffer' is the output buffer pointer
\r
2479 ** 'length' is the number of samples that should be generated
\r
2481 void ym3526_update_one(void *chip, OPLSAMPLE **buffer, int length)
\r
2483 FM_OPL *OPL = (FM_OPL *)chip;
\r
2484 UINT8 rhythm = OPL->rhythm&0x20;
\r
2485 OPLSAMPLE *bufL = buffer[0];
\r
2486 OPLSAMPLE *bufR = buffer[1];
\r
2489 for( i=0; i < length ; i++ )
\r
2493 OPL->output[0] = 0;
\r
2498 OPL_CALC_CH(OPL, &OPL->P_CH[0]);
\r
2499 OPL_CALC_CH(OPL, &OPL->P_CH[1]);
\r
2500 OPL_CALC_CH(OPL, &OPL->P_CH[2]);
\r
2501 OPL_CALC_CH(OPL, &OPL->P_CH[3]);
\r
2502 OPL_CALC_CH(OPL, &OPL->P_CH[4]);
\r
2503 OPL_CALC_CH(OPL, &OPL->P_CH[5]);
\r
2507 OPL_CALC_CH(OPL, &OPL->P_CH[6]);
\r
2508 OPL_CALC_CH(OPL, &OPL->P_CH[7]);
\r
2509 OPL_CALC_CH(OPL, &OPL->P_CH[8]);
\r
2511 else /* Rhythm part */
\r
2513 OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
\r
2516 lt = OPL->output[0];
\r
2521 //lt = limit( lt , MAXOUT, MINOUT );
\r
2523 #ifdef SAVE_SAMPLE
\r
2530 /* store to sound buffer */
\r
2538 #endif /* BUILD_YM3526 */
\r
2545 static void Y8950_deltat_status_set(void *chip, UINT8 changebits)
\r
2547 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2548 OPL_STATUS_SET(Y8950, changebits);
\r
2550 static void Y8950_deltat_status_reset(void *chip, UINT8 changebits)
\r
2552 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2553 OPL_STATUS_RESET(Y8950, changebits);
\r
2556 void *y8950_init(UINT32 clock, UINT32 rate)
\r
2558 /* emulator create */
\r
2559 FM_OPL *Y8950 = OPLCreate(clock,rate,OPL_TYPE_Y8950);
\r
2562 Y8950->deltat->status_set_handler = Y8950_deltat_status_set;
\r
2563 Y8950->deltat->status_reset_handler = Y8950_deltat_status_reset;
\r
2564 Y8950->deltat->status_change_which_chip = Y8950;
\r
2565 Y8950->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */
\r
2566 Y8950->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */
\r
2568 /*Y8950->deltat->write_time = 10.0 / clock;*/ /* a single byte write takes 10 cycles of main clock */
\r
2569 /*Y8950->deltat->read_time = 8.0 / clock;*/ /* a single byte read takes 8 cycles of main clock */
\r
2571 //OPL_save_state(Y8950);
\r
2572 y8950_reset_chip(Y8950);
\r
2578 void y8950_shutdown(void *chip)
\r
2580 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2582 free(Y8950->deltat->memory); Y8950->deltat->memory = NULL;
\r
2584 /* emulator shutdown */
\r
2585 OPLDestroy(Y8950);
\r
2587 void y8950_reset_chip(void *chip)
\r
2589 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2590 OPLResetChip(Y8950);
\r
2593 int y8950_write(void *chip, int a, int v)
\r
2595 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2596 return OPLWrite(Y8950, a, v);
\r
2599 unsigned char y8950_read(void *chip, int a)
\r
2601 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2602 return OPLRead(Y8950, a);
\r
2604 int y8950_timer_over(void *chip, int c)
\r
2606 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2607 return OPLTimerOver(Y8950, c);
\r
2610 void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param)
\r
2612 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2613 OPLSetTimerHandler(Y8950, timer_handler, param);
\r
2615 void y8950_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param)
\r
2617 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2618 OPLSetIRQHandler(Y8950, IRQHandler, param);
\r
2620 void y8950_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param)
\r
2622 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2623 OPLSetUpdateHandler(Y8950, UpdateHandler, param);
\r
2626 void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size )
\r
2628 FM_OPL *OPL = (FM_OPL *)chip;
\r
2629 OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr);
\r
2630 OPL->deltat->memory_size = deltat_mem_size;
\r
2633 void y8950_write_pcmrom(void *chip, offs_t ROMSize, offs_t DataStart,
\r
2634 offs_t DataLength, const UINT8* ROMData)
\r
2636 FM_OPL *Y8950 = (FM_OPL *)chip;
\r
2638 if (Y8950->deltat->memory_size != ROMSize)
\r
2640 Y8950->deltat->memory = (UINT8*)realloc(Y8950->deltat->memory, ROMSize);
\r
2641 Y8950->deltat->memory_size = ROMSize;
\r
2642 memset(Y8950->deltat->memory, 0xFF, ROMSize);
\r
2643 YM_DELTAT_calc_mem_mask(Y8950->deltat);
\r
2645 if (DataStart > ROMSize)
\r
2647 if (DataStart + DataLength > ROMSize)
\r
2648 DataLength = ROMSize - DataStart;
\r
2650 memcpy(Y8950->deltat->memory + DataStart, ROMData, DataLength);
\r
2656 ** Generate samples for one of the Y8950's
\r
2658 ** 'which' is the virtual Y8950 number
\r
2659 ** '*buffer' is the output buffer pointer
\r
2660 ** 'length' is the number of samples that should be generated
\r
2662 void y8950_update_one(void *chip, OPLSAMPLE **buffer, int length)
\r
2665 FM_OPL *OPL = (FM_OPL *)chip;
\r
2666 UINT8 rhythm = OPL->rhythm&0x20;
\r
2667 YM_DELTAT *DELTAT = OPL->deltat;
\r
2668 OPLSAMPLE *bufL = buffer[0];
\r
2669 OPLSAMPLE *bufR = buffer[1];
\r
2671 for( i=0; i < length ; i++ )
\r
2675 OPL->output[0] = 0;
\r
2676 OPL->output_deltat[0] = 0;
\r
2680 /* deltaT ADPCM */
\r
2681 if( DELTAT->portstate&0x80 && ! OPL->MuteSpc[5] )
\r
2682 YM_DELTAT_ADPCM_CALC(DELTAT);
\r
2685 OPL_CALC_CH(OPL, &OPL->P_CH[0]);
\r
2686 OPL_CALC_CH(OPL, &OPL->P_CH[1]);
\r
2687 OPL_CALC_CH(OPL, &OPL->P_CH[2]);
\r
2688 OPL_CALC_CH(OPL, &OPL->P_CH[3]);
\r
2689 OPL_CALC_CH(OPL, &OPL->P_CH[4]);
\r
2690 OPL_CALC_CH(OPL, &OPL->P_CH[5]);
\r
2694 OPL_CALC_CH(OPL, &OPL->P_CH[6]);
\r
2695 OPL_CALC_CH(OPL, &OPL->P_CH[7]);
\r
2696 OPL_CALC_CH(OPL, &OPL->P_CH[8]);
\r
2698 else /* Rhythm part */
\r
2700 OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
\r
2703 lt = OPL->output[0] + (OPL->output_deltat[0]>>11);
\r
2708 //lt = limit( lt , MAXOUT, MINOUT );
\r
2710 #ifdef SAVE_SAMPLE
\r
2717 /* store to sound buffer */
\r
2726 void y8950_set_port_handler(void *chip,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,void * param)
\r
2728 FM_OPL *OPL = (FM_OPL *)chip;
\r
2729 OPL->porthandler_w = PortHandler_w;
\r
2730 OPL->porthandler_r = PortHandler_r;
\r
2731 OPL->port_param = param;
\r
2734 void y8950_set_keyboard_handler(void *chip,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,void * param)
\r
2736 FM_OPL *OPL = (FM_OPL *)chip;
\r
2737 OPL->keyboardhandler_w = KeyboardHandler_w;
\r
2738 OPL->keyboardhandler_r = KeyboardHandler_r;
\r
2739 OPL->keyboard_param = param;
\r
2744 void opl_set_mute_mask(void *chip, UINT32 MuteMask)
\r
2746 FM_OPL *opl = (FM_OPL *)chip;
\r
2749 for (CurChn = 0; CurChn < 9; CurChn ++)
\r
2750 opl->P_CH[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
\r
2751 for (CurChn = 0; CurChn < 6; CurChn ++)
\r
2752 opl->MuteSpc[CurChn] = (MuteMask >> (9 + CurChn)) & 0x01;
\r