summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c2565
1 files changed, 2565 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c b/apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c
new file mode 100644
index 0000000000..41178d6bd9
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/fmopl_gpl.c
@@ -0,0 +1,2565 @@
1/*
2 * Rockbox notes:
3 *
4 * This file is originally from the MAME project, from after their
5 * GPLv2 relicense. I (Franklin Wei) have made some modifications
6 * since then to make it work with the Wolf4SDL source. Notably, I
7 * corrected the behavior of YM3812Write() to write directly to the
8 * registers. Additionally, I fixed an unaligned write in OPL_CALC_CH
9 * which caused terrible output on ARM.
10 */
11
12// license:GPL-2.0+
13// copyright-holders:Jarek Burczynski,Tatsuyuki Satoh
14/*
15**
16** File: fmopl.c - software implementation of FM sound generator
17** types OPL and OPL2
18**
19** Copyright Jarek Burczynski (bujar at mame dot net)
20** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development
21**
22** Version 0.72
23**
24
25Revision History:
26
2704-08-2003 Jarek Burczynski:
28- removed BFRDY hack. BFRDY is busy flag, and it should be 0 only when the chip
29handles memory read/write or during the adpcm synthesis when the chip
30requests another byte of ADPCM data.
31
3224-07-2003 Jarek Burczynski:
33- added a small hack for Y8950 status BFRDY flag (bit 3 should be set after
34some (unknown) delay). Right now it's always set.
35
3614-06-2003 Jarek Burczynski:
37- implemented all of the status register flags in Y8950 emulation
38- renamed y8950_set_delta_t_memory() parameters from _rom_ to _mem_ since
39they can be either RAM or ROM
40
4108-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip)
42- corrected ym3526_read() to always set bit 2 and bit 1
43to HIGH state - identical to ym3812_read (verified on real YM3526)
44
4504-28-2002 Jarek Burczynski:
46- binary exact Envelope Generator (verified on real YM3812);
47compared to YM2151: the EG clock is equal to internal_clock,
48rates are 2 times slower and volume resolution is one bit less
49- modified interface functions (they no longer return pointer -
50that's internal to the emulator now):
51- new wrapper functions for OPLCreate: ym3526_init(), ym3812_init() and y8950_init()
52- corrected 'off by one' error in feedback calculations (when feedback is off)
53- enabled waveform usage (credit goes to Vlad Romascanu and zazzal22)
54- speeded up noise generator calculations (Nicola Salmoria)
55
5603-24-2002 Jarek Burczynski (thanks to Dox for the YM3812 chip)
57Complete rewrite (all verified on real YM3812):
58- corrected sin_tab and tl_tab data
59- corrected operator output calculations
60- corrected waveform_select_enable register;
61simply: ignore all writes to waveform_select register when
62waveform_select_enable == 0 and do not change the waveform previously selected.
63- corrected KSR handling
64- corrected Envelope Generator: attack shape, Sustain mode and
65Percussive/Non-percussive modes handling
66- Envelope Generator rates are two times slower now
67- LFO amplitude (tremolo) and phase modulation (vibrato)
68- rhythm sounds phase generation
69- white noise generator (big thanks to Olivier Galibert for mentioning Berlekamp-Massey algorithm)
70- corrected key on/off handling (the 'key' signal is ORed from three sources: FM, rhythm and CSM)
71- funky details (like ignoring output of operator 1 in BD rhythm sound when connect == 1)
72
7312-28-2001 Acho A. Tang
74- reflected Delta-T EOS status on Y8950 status port.
75- fixed subscription range of attack/decay tables
76
77
78To do:
79add delay before key off in CSM mode (see CSMKeyControll)
80verify volume of the FM part on the Y8950
81*/
82
83#include "fmopl.h"
84
85
86
87/* output final shift */
88#if (OPL_SAMPLE_BITS==16)
89#define FINAL_SH (0)
90#define MAXOUT (+32767)
91#define MINOUT (-32768)
92#else
93#define FINAL_SH (8)
94#define MAXOUT (+127)
95#define MINOUT (-128)
96#endif
97
98
99#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
100#define EG_SH 16 /* 16.16 fixed point (EG timing) */
101#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */
102#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */
103
104#define FREQ_MASK ((1<<FREQ_SH)-1)
105
106/* envelope output entries */
107#define ENV_BITS 10
108#define ENV_LEN (1<<ENV_BITS)
109#define ENV_STEP (128.0/ENV_LEN)
110
111#define MAX_ATT_INDEX ((1<<(ENV_BITS-1))-1) /*511*/
112#define MIN_ATT_INDEX (0)
113
114/* sinwave entries */
115#define SIN_BITS 10
116#define SIN_LEN (1<<SIN_BITS)
117#define SIN_MASK (SIN_LEN-1)
118
119#define TL_RES_LEN (256) /* 8 bits addressing (real chip) */
120
121
122
123/* register number to channel number , slot offset */
124#define SLOT1 0
125#define SLOT2 1
126
127/* Envelope Generator phases */
128
129#define EG_ATT 4
130#define EG_DEC 3
131#define EG_SUS 2
132#define EG_REL 1
133#define EG_OFF 0
134
135
136/* save output as raw 16-bit sample */
137
138/*#define SAVE_SAMPLE*/
139
140#ifdef SAVE_SAMPLE
141static signed int acc_calc(signed int value)
142{
143 if (value>=0)
144 {
145 if (value < 0x0200)
146 return (value & ~0);
147 if (value < 0x0400)
148 return (value & ~1);
149 if (value < 0x0800)
150 return (value & ~3);
151 if (value < 0x1000)
152 return (value & ~7);
153 if (value < 0x2000)
154 return (value & ~15);
155 if (value < 0x4000)
156 return (value & ~31);
157 return (value & ~63);
158 }
159 /*else value < 0*/
160 if (value > -0x0200)
161 return (~abs(value) & ~0);
162 if (value > -0x0400)
163 return (~abs(value) & ~1);
164 if (value > -0x0800)
165 return (~abs(value) & ~3);
166 if (value > -0x1000)
167 return (~abs(value) & ~7);
168 if (value > -0x2000)
169 return (~abs(value) & ~15);
170 if (value > -0x4000)
171 return (~abs(value) & ~31);
172 return (~abs(value) & ~63);
173}
174
175
176static FILE *sample[1];
177#if 1 /*save to MONO file */
178#define SAVE_ALL_CHANNELS \
179 { signed int pom = acc_calc(lt); \
180 fputc((unsigned short)pom&0xff,sample[0]); \
181 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
182 }
183#else /*save to STEREO file */
184#define SAVE_ALL_CHANNELS \
185 { signed int pom = lt; \
186 fputc((unsigned short)pom&0xff,sample[0]); \
187 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
188 pom = rt; \
189 fputc((unsigned short)pom&0xff,sample[0]); \
190 fputc(((unsigned short)pom>>8)&0xff,sample[0]); \
191 }
192#endif
193#endif
194
195#define LOG_CYM_FILE 0
196static FILE * cymfile = NULL;
197
198
199
200#define OPL_TYPE_WAVESEL 0x01 /* waveform select */
201#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */
202#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */
203#define OPL_TYPE_IO 0x08 /* I/O port */
204
205/* ---------- Generic interface section ---------- */
206#define OPL_TYPE_YM3526 (0)
207#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
208#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
209
210
211
212struct OPL_SLOT
213{
214 UINT32 ar; /* attack rate: AR<<2 */
215 UINT32 dr; /* decay rate: DR<<2 */
216 UINT32 rr; /* release rate:RR<<2 */
217 UINT8 KSR; /* key scale rate */
218 UINT8 ksl; /* keyscale level */
219 UINT8 ksr; /* key scale rate: kcode>>KSR */
220 UINT8 mul; /* multiple: mul_tab[ML] */
221
222 /* Phase Generator */
223 UINT32 Cnt; /* frequency counter */
224 UINT32 Incr; /* frequency counter step */
225 UINT8 FB; /* feedback shift value */
226 INT32 *connect1; /* slot1 output pointer */
227 INT32 op1_out[2]; /* slot1 output for feedback */
228 UINT8 CON; /* connection (algorithm) type */
229
230 /* Envelope Generator */
231 UINT8 eg_type; /* percussive/non-percussive mode */
232 UINT8 state; /* phase type */
233 UINT32 TL; /* total level: TL << 2 */
234 INT32 TLL; /* adjusted now TL */
235 INT32 volume; /* envelope counter */
236 UINT32 sl; /* sustain level: sl_tab[SL] */
237 UINT8 eg_sh_ar; /* (attack state) */
238 UINT8 eg_sel_ar; /* (attack state) */
239 UINT8 eg_sh_dr; /* (decay state) */
240 UINT8 eg_sel_dr; /* (decay state) */
241 UINT8 eg_sh_rr; /* (release state) */
242 UINT8 eg_sel_rr; /* (release state) */
243 UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */
244
245 /* LFO */
246 UINT32 AMmask; /* LFO Amplitude Modulation enable mask */
247 UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/
248
249 /* waveform select */
250 UINT16 wavetable;
251};
252
253typedef struct OPL_SLOT OPL_SLOT;
254
255struct OPL_CH
256{
257 OPL_SLOT SLOT[2];
258 /* phase generator state */
259 UINT32 block_fnum; /* block+fnum */
260 UINT32 fc; /* Freq. Increment base */
261 UINT32 ksl_base; /* KeyScaleLevel Base step */
262 UINT8 kcode; /* key code (for key scaling) */
263};
264
265typedef struct OPL_CH OPL_CH;
266
267/* OPL state */
268struct FM_OPL
269{
270 // moved to beginning to fix alignment
271 signed int phase_modulation __attribute__((aligned)); /* phase modulation input (SLOT 2) */
272 signed int output[1] __attribute__((aligned));
273
274 /* FM channel slots */
275 OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/
276
277 UINT32 eg_cnt; /* global envelope generator counter */
278 UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */
279 UINT32 eg_timer_add; /* step of eg_timer */
280 UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */
281
282 UINT8 rhythm; /* Rhythm mode */
283
284 UINT32 fn_tab[1024]; /* fnumber->increment counter */
285
286 /* LFO */
287 UINT32 LFO_AM;
288 INT32 LFO_PM;
289
290 UINT8 lfo_am_depth;
291 UINT8 lfo_pm_depth_range;
292 UINT32 lfo_am_cnt;
293 UINT32 lfo_am_inc;
294 UINT32 lfo_pm_cnt;
295 UINT32 lfo_pm_inc;
296
297 UINT32 noise_rng; /* 23 bit noise shift register */
298 UINT32 noise_p; /* current noise 'phase' */
299 UINT32 noise_f; /* current noise period */
300
301 UINT8 wavesel; /* waveform select enable flag */
302
303 UINT32 T[2]; /* timer counters */
304 UINT8 st[2]; /* timer enable */
305
306#if BUILD_Y8950
307 /* Delta-T ADPCM unit (Y8950) */
308
309 YM_DELTAT *deltat;
310
311 /* Keyboard and I/O ports interface */
312 UINT8 portDirection;
313 UINT8 portLatch;
314 OPL_PORTHANDLER_R porthandler_r;
315 OPL_PORTHANDLER_W porthandler_w;
316 void * port_param;
317 OPL_PORTHANDLER_R keyboardhandler_r;
318 OPL_PORTHANDLER_W keyboardhandler_w;
319 void * keyboard_param;
320#endif
321
322 /* external event callback handlers */
323 OPL_TIMERHANDLER timer_handler; /* TIMER handler */
324 void *TimerParam; /* TIMER parameter */
325 OPL_IRQHANDLER IRQHandler; /* IRQ handler */
326 void *IRQParam; /* IRQ parameter */
327 OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */
328 void *UpdateParam; /* stream update parameter */
329
330 UINT8 type; /* chip type */
331 UINT8 address; /* address register */
332 UINT8 status; /* status flag */
333 UINT8 statusmask; /* status mask */
334 UINT8 mode; /* Reg.08 : CSM,notesel,etc. */
335
336 UINT32 clock; /* master clock (Hz) */
337 UINT32 rate; /* sampling rate (Hz) */
338 double freqbase; /* frequency base */
339 double TimerBase; /* Timer base time (==sampling time)*/
340 device_t *device;
341
342#if BUILD_Y8950
343 INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */
344#endif
345} __attribute__((aligned));
346
347typedef struct FM_OPL FM_OPL;
348
349/* mapping of register number (offset) to slot number used by the emulator */
350static const int slot_array[32]=
351{
352 0, 2, 4, 1, 3, 5,-1,-1,
353 6, 8,10, 7, 9,11,-1,-1,
354 12,14,16,13,15,17,-1,-1,
355 -1,-1,-1,-1,-1,-1,-1,-1
356};
357
358/* key scale level */
359/* table is 3dB/octave , DV converts this into 6dB/octave */
360/* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */
361#define DV (0.1875/2.0)
362static const UINT32 ksl_tab[8*16]=
363{
364 /* OCT 0 */
365 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
366 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
367 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
368 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
369 /* OCT 1 */
370 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
371 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
372 0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
373 1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
374 /* OCT 2 */
375 0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
376 0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
377 3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
378 4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
379 /* OCT 3 */
380 0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
381 3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
382 6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
383 7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
384 /* OCT 4 */
385 0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
386 6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
387 9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
388 10.875/DV,11.250/DV,11.625/DV,12.000/DV,
389 /* OCT 5 */
390 0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
391 9.000/DV,10.125/DV,10.875/DV,11.625/DV,
392 12.000/DV,12.750/DV,13.125/DV,13.500/DV,
393 13.875/DV,14.250/DV,14.625/DV,15.000/DV,
394 /* OCT 6 */
395 0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
396 12.000/DV,13.125/DV,13.875/DV,14.625/DV,
397 15.000/DV,15.750/DV,16.125/DV,16.500/DV,
398 16.875/DV,17.250/DV,17.625/DV,18.000/DV,
399 /* OCT 7 */
400 0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
401 15.000/DV,16.125/DV,16.875/DV,17.625/DV,
402 18.000/DV,18.750/DV,19.125/DV,19.500/DV,
403 19.875/DV,20.250/DV,20.625/DV,21.000/DV
404};
405#undef DV
406
407/* 0 / 3.0 / 1.5 / 6.0 dB/OCT */
408static const UINT32 ksl_shift[4] = { 31, 1, 2, 0 };
409
410
411/* sustain level table (3dB per step) */
412/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
413#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) )
414static const UINT32 sl_tab[16]={
415 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
416 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
417};
418#undef SC
419
420
421#define RATE_STEPS (8)
422static const unsigned char eg_inc[15*RATE_STEPS]={
423/*cycle:0 1 2 3 4 5 6 7*/
424
425 /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */
426 /* 1 */ 0,1, 0,1, 1,1, 0,1, /* rates 00..12 1 */
427 /* 2 */ 0,1, 1,1, 0,1, 1,1, /* rates 00..12 2 */
428 /* 3 */ 0,1, 1,1, 1,1, 1,1, /* rates 00..12 3 */
429
430 /* 4 */ 1,1, 1,1, 1,1, 1,1, /* rate 13 0 (increment by 1) */
431 /* 5 */ 1,1, 1,2, 1,1, 1,2, /* rate 13 1 */
432 /* 6 */ 1,2, 1,2, 1,2, 1,2, /* rate 13 2 */
433 /* 7 */ 1,2, 2,2, 1,2, 2,2, /* rate 13 3 */
434
435 /* 8 */ 2,2, 2,2, 2,2, 2,2, /* rate 14 0 (increment by 2) */
436 /* 9 */ 2,2, 2,4, 2,2, 2,4, /* rate 14 1 */
437 /*10 */ 2,4, 2,4, 2,4, 2,4, /* rate 14 2 */
438 /*11 */ 2,4, 4,4, 2,4, 4,4, /* rate 14 3 */
439
440 /*12 */ 4,4, 4,4, 4,4, 4,4, /* rates 15 0, 15 1, 15 2, 15 3 (increment by 4) */
441 /*13 */ 8,8, 8,8, 8,8, 8,8, /* rates 15 2, 15 3 for attack */
442 /*14 */ 0,0, 0,0, 0,0, 0,0, /* infinity rates for attack and decay(s) */
443};
444
445
446#define O(a) (a*RATE_STEPS)
447
448/*note that there is no O(13) in this table - it's directly in the code */
449static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */
450/* 16 infinite time rates */
451 O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
452 O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14),
453
454/* rates 00-12 */
455 O( 0),O( 1),O( 2),O( 3),
456 O( 0),O( 1),O( 2),O( 3),
457 O( 0),O( 1),O( 2),O( 3),
458 O( 0),O( 1),O( 2),O( 3),
459 O( 0),O( 1),O( 2),O( 3),
460 O( 0),O( 1),O( 2),O( 3),
461 O( 0),O( 1),O( 2),O( 3),
462 O( 0),O( 1),O( 2),O( 3),
463 O( 0),O( 1),O( 2),O( 3),
464 O( 0),O( 1),O( 2),O( 3),
465 O( 0),O( 1),O( 2),O( 3),
466 O( 0),O( 1),O( 2),O( 3),
467 O( 0),O( 1),O( 2),O( 3),
468
469/* rate 13 */
470 O( 4),O( 5),O( 6),O( 7),
471
472/* rate 14 */
473 O( 8),O( 9),O(10),O(11),
474
475/* rate 15 */
476 O(12),O(12),O(12),O(12),
477
478/* 16 dummy rates (same as 15 3) */
479 O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
480 O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12),
481
482};
483#undef O
484
485/*rate 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 */
486/*shift 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 */
487/*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */
488
489#define O(a) (a*1)
490static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */
491/* 16 infinite time rates */
492 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
493 O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),
494
495/* rates 00-12 */
496 O(12),O(12),O(12),O(12),
497 O(11),O(11),O(11),O(11),
498 O(10),O(10),O(10),O(10),
499 O( 9),O( 9),O( 9),O( 9),
500 O( 8),O( 8),O( 8),O( 8),
501 O( 7),O( 7),O( 7),O( 7),
502 O( 6),O( 6),O( 6),O( 6),
503 O( 5),O( 5),O( 5),O( 5),
504 O( 4),O( 4),O( 4),O( 4),
505 O( 3),O( 3),O( 3),O( 3),
506 O( 2),O( 2),O( 2),O( 2),
507 O( 1),O( 1),O( 1),O( 1),
508 O( 0),O( 0),O( 0),O( 0),
509
510/* rate 13 */
511 O( 0),O( 0),O( 0),O( 0),
512
513/* rate 14 */
514 O( 0),O( 0),O( 0),O( 0),
515
516/* rate 15 */
517 O( 0),O( 0),O( 0),O( 0),
518
519/* 16 dummy rates (same as 15 3) */
520 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
521 O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),
522
523};
524#undef O
525
526
527/* multiple table */
528#define ML 2
529static const UINT8 mul_tab[16]= {
530/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */
531 ML/2, 1*ML, 2*ML, 3*ML, 4*ML, 5*ML, 6*ML, 7*ML,
532 8*ML, 9*ML,10*ML,10*ML,12*ML,12*ML,15*ML,15*ML
533};
534#undef ML
535
536/* TL_TAB_LEN is calculated as:
537 * 12 - sinus amplitude bits (Y axis)
538 * 2 - sinus sign bit (Y axis)
539 * TL_RES_LEN - sinus resolution (X axis)
540 */
541#define TL_TAB_LEN (12*2*TL_RES_LEN)
542static signed int tl_tab[TL_TAB_LEN];
543
544#define ENV_QUIET (TL_TAB_LEN>>4)
545
546/* sin waveform table in 'decibel' scale */
547/* four waveforms on OPL2 type chips */
548static unsigned int sin_tab[SIN_LEN * 4];
549
550
551/* LFO Amplitude Modulation table (verified on real YM3812)
552 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples
553
554 Length: 210 elements.
555
556 Each of the elements has to be repeated
557 exactly 64 times (on 64 consecutive samples).
558 The whole table takes: 64 * 210 = 13440 samples.
559
560 When AM = 1 data is used directly
561 When AM = 0 data is divided by 4 before being used (losing precision is important)
562*/
563
564#define LFO_AM_TAB_ELEMENTS 210
565
566static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = {
567 0,0,0,0,0,0,0,
568 1,1,1,1,
569 2,2,2,2,
570 3,3,3,3,
571 4,4,4,4,
572 5,5,5,5,
573 6,6,6,6,
574 7,7,7,7,
575 8,8,8,8,
576 9,9,9,9,
577 10,10,10,10,
578 11,11,11,11,
579 12,12,12,12,
580 13,13,13,13,
581 14,14,14,14,
582 15,15,15,15,
583 16,16,16,16,
584 17,17,17,17,
585 18,18,18,18,
586 19,19,19,19,
587 20,20,20,20,
588 21,21,21,21,
589 22,22,22,22,
590 23,23,23,23,
591 24,24,24,24,
592 25,25,25,25,
593 26,26,26,
594 25,25,25,25,
595 24,24,24,24,
596 23,23,23,23,
597 22,22,22,22,
598 21,21,21,21,
599 20,20,20,20,
600 19,19,19,19,
601 18,18,18,18,
602 17,17,17,17,
603 16,16,16,16,
604 15,15,15,15,
605 14,14,14,14,
606 13,13,13,13,
607 12,12,12,12,
608 11,11,11,11,
609 10,10,10,10,
610 9,9,9,9,
611 8,8,8,8,
612 7,7,7,7,
613 6,6,6,6,
614 5,5,5,5,
615 4,4,4,4,
616 3,3,3,3,
617 2,2,2,2,
618 1,1,1,1
619};
620
621/* LFO Phase Modulation table (verified on real YM3812) */
622static const INT8 lfo_pm_table[8*8*2] = {
623/* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */
624 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
625 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/
626
627/* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */
628 0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/
629 1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/
630
631/* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */
632 1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/
633 2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/
634
635/* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */
636 1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/
637 3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/
638
639/* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */
640 2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/
641 4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/
642
643/* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */
644 2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/
645 5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/
646
647/* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */
648 3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/
649 6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/
650
651/* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */
652 3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/
653 7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/
654};
655
656
657/* lock level of common table */
658static int num_lock = 0;
659
660
661#define SLOT7_1 (&OPL->P_CH[7].SLOT[SLOT1])
662#define SLOT7_2 (&OPL->P_CH[7].SLOT[SLOT2])
663#define SLOT8_1 (&OPL->P_CH[8].SLOT[SLOT1])
664#define SLOT8_2 (&OPL->P_CH[8].SLOT[SLOT2])
665
666
667
668
669static int limit( int val, int max, int min ) {
670 if ( val > max )
671 val = max;
672 else if ( val < min )
673 val = min;
674
675 return val;
676}
677
678
679/* status set and IRQ handling */
680static void OPL_STATUS_SET(FM_OPL *OPL,int flag)
681{
682 /* set status flag */
683 OPL->status |= flag;
684 if(!(OPL->status & 0x80))
685 {
686 if(OPL->status & OPL->statusmask)
687 { /* IRQ on */
688 OPL->status |= 0x80;
689 /* callback user interrupt handler (IRQ is OFF to ON) */
690 if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
691 }
692 }
693}
694
695/* status reset and IRQ handling */
696static void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
697{
698 /* reset status flag */
699 OPL->status &=~flag;
700 if((OPL->status & 0x80))
701 {
702 if (!(OPL->status & OPL->statusmask) )
703 {
704 OPL->status &= 0x7f;
705 /* callback user interrupt handler (IRQ is ON to OFF) */
706 if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
707 }
708 }
709}
710
711/* IRQ mask set */
712static void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
713{
714 OPL->statusmask = flag;
715 /* IRQ handling check */
716 OPL_STATUS_SET(OPL,0);
717 OPL_STATUS_RESET(OPL,0);
718}
719
720
721/* advance LFO to next sample */
722static void advance_lfo(FM_OPL *OPL)
723{
724 UINT8 tmp;
725
726 /* LFO */
727 OPL->lfo_am_cnt += OPL->lfo_am_inc;
728// if (OPL->lfo_am_cnt >= ((UINT32)LFO_AM_TAB_ELEMENTS<<LFO_SH) ) /* lfo_am_table is 210 elements long */
729// OPL->lfo_am_cnt -= ((UINT32)LFO_AM_TAB_ELEMENTS<<LFO_SH);
730 if (OPL->lfo_am_cnt >= (LFO_AM_TAB_ELEMENTS<<LFO_SH) ) /* lfo_am_table is 210 elements long */
731 OPL->lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<<LFO_SH);
732
733 tmp = lfo_am_table[ OPL->lfo_am_cnt >> LFO_SH ];
734
735 if (OPL->lfo_am_depth)
736 OPL->LFO_AM = tmp;
737 else
738 OPL->LFO_AM = tmp>>2;
739
740 OPL->lfo_pm_cnt += OPL->lfo_pm_inc;
741 OPL->LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range;
742}
743
744/* advance to next sample */
745static void advance(FM_OPL *OPL)
746{
747 OPL_CH *CH;
748 OPL_SLOT *op;
749 int i;
750
751 OPL->eg_timer += OPL->eg_timer_add;
752
753 while (OPL->eg_timer >= OPL->eg_timer_overflow)
754 {
755 OPL->eg_timer -= OPL->eg_timer_overflow;
756
757 OPL->eg_cnt++;
758
759 for (i=0; i<9*2; i++)
760 {
761 CH = &OPL->P_CH[i/2];
762 op = &CH->SLOT[i&1];
763
764 /* Envelope Generator */
765 switch(op->state)
766 {
767 case EG_ATT: /* attack phase */
768 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_ar)-1) ) )
769 {
770 op->volume += (~op->volume *
771 (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)])
772 ) >>3;
773
774 if (op->volume <= MIN_ATT_INDEX)
775 {
776 op->volume = MIN_ATT_INDEX;
777 op->state = EG_DEC;
778 }
779
780 }
781 break;
782
783 case EG_DEC: /* decay phase */
784 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_dr)-1) ) )
785 {
786 op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)];
787
788 if ( (UINT32) op->volume >= op->sl )
789 op->state = EG_SUS;
790
791 }
792 break;
793
794 case EG_SUS: /* sustain phase */
795
796 /* this is important behaviour:
797 one can change percusive/non-percussive modes on the fly and
798 the chip will remain in sustain phase - verified on real YM3812 */
799
800 if(op->eg_type) /* non-percussive mode */
801 {
802 /* do nothing */
803 }
804 else /* percussive mode */
805 {
806 /* during sustain phase chip adds Release Rate (in percussive mode) */
807 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
808 {
809 op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
810
811 if ( op->volume >= MAX_ATT_INDEX )
812 op->volume = MAX_ATT_INDEX;
813 }
814 /* else do nothing in sustain phase */
815 }
816 break;
817
818 case EG_REL: /* release phase */
819 if ( !(OPL->eg_cnt & ((1<<op->eg_sh_rr)-1) ) )
820 {
821 op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)];
822
823 if ( op->volume >= MAX_ATT_INDEX )
824 {
825 op->volume = MAX_ATT_INDEX;
826 op->state = EG_OFF;
827 }
828
829 }
830 break;
831
832 default:
833 break;
834 }
835 }
836 }
837
838 for (i=0; i<9*2; i++)
839 {
840 CH = &OPL->P_CH[i/2];
841 op = &CH->SLOT[i&1];
842
843 /* Phase Generator */
844 if(op->vib)
845 {
846 UINT8 block;
847 unsigned int block_fnum = CH->block_fnum;
848
849 unsigned int fnum_lfo = (block_fnum&0x0380) >> 7;
850
851 signed int lfo_fn_table_index_offset = lfo_pm_table[OPL->LFO_PM + 16*fnum_lfo ];
852
853 if (lfo_fn_table_index_offset) /* LFO phase modulation active */
854 {
855 block_fnum += lfo_fn_table_index_offset;
856 block = (block_fnum&0x1c00) >> 10;
857 op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul;
858 }
859 else /* LFO phase modulation = zero */
860 {
861 op->Cnt += op->Incr;
862 }
863 }
864 else /* LFO phase modulation disabled for this operator */
865 {
866 op->Cnt += op->Incr;
867 }
868 }
869
870 /* The Noise Generator of the YM3812 is 23-bit shift register.
871 * Period is equal to 2^23-2 samples.
872 * Register works at sampling frequency of the chip, so output
873 * can change on every sample.
874 *
875 * Output of the register and input to the bit 22 is:
876 * bit0 XOR bit14 XOR bit15 XOR bit22
877 *
878 * Simply use bit 22 as the noise output.
879 */
880
881 OPL->noise_p += OPL->noise_f;
882 i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */
883 OPL->noise_p &= FREQ_MASK;
884 while (i)
885 {
886 /*
887 UINT32 j;
888 j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1;
889 OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1);
890 */
891
892 /*
893 Instead of doing all the logic operations above, we
894 use a trick here (and use bit 0 as the noise output).
895 The difference is only that the noise bit changes one
896 step ahead. This doesn't matter since we don't know
897 what is real state of the noise_rng after the reset.
898 */
899
900 if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302;
901 OPL->noise_rng >>= 1;
902
903 i--;
904 }
905}
906
907
908static signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab)
909{
910 UINT32 p;
911
912 p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ];
913
914 if (p >= TL_TAB_LEN)
915 return 0;
916 return tl_tab[p];
917}
918
919static signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab)
920{
921 UINT32 p;
922
923 p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ];
924
925 if (p >= TL_TAB_LEN)
926 return 0;
927 return tl_tab[p];
928}
929
930
931#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (OPL->LFO_AM & (OP)->AMmask))
932
933/* calculate output */
934static void OPL_CALC_CH( FM_OPL *OPL, OPL_CH *CH )
935{
936 OPL_SLOT *SLOT;
937 unsigned int env;
938 signed int out;
939
940 OPL->phase_modulation = 0;
941
942 /* SLOT 1 */
943 SLOT = &CH->SLOT[SLOT1];
944 env = volume_calc(SLOT);
945 out = SLOT->op1_out[0] + SLOT->op1_out[1];
946 SLOT->op1_out[0] = SLOT->op1_out[1];
947
948 //INT32 a;
949 //memcpy(&a, SLOT->connect1, sizeof(a));
950 //a += SLOT->op1_out[0];
951 //memcpy(SLOT->connect1, &a, sizeof(a));
952
953 *SLOT->connect1 += SLOT->op1_out[0]; // alignment issue on arm
954 SLOT->op1_out[1] = 0;
955 if( env < ENV_QUIET )
956 {
957 if (!SLOT->FB)
958 out = 0;
959 SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<<SLOT->FB), SLOT->wavetable );
960 }
961 /* SLOT 2 */
962 SLOT++;
963 env = volume_calc(SLOT);
964 if( env < ENV_QUIET )
965 {
966 OPL->output[0] += op_calc(SLOT->Cnt, env, OPL->phase_modulation, SLOT->wavetable);
967 }
968}
969
970/*
971 operators used in the rhythm sounds generation process:
972
973 Envelope Generator:
974
975 channel operator register number Bass High Snare Tom Top
976 / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal
977 6 / 0 12 50 70 90 f0 +
978 6 / 1 15 53 73 93 f3 +
979 7 / 0 13 51 71 91 f1 +
980 7 / 1 16 54 74 94 f4 +
981 8 / 0 14 52 72 92 f2 +
982 8 / 1 17 55 75 95 f5 +
983
984 Phase Generator:
985
986 channel operator register number Bass High Snare Tom Top
987 / slot number MULTIPLE Drum Hat Drum Tom Cymbal
988 6 / 0 12 30 +
989 6 / 1 15 33 +
990 7 / 0 13 31 + + +
991 7 / 1 16 34 ----- n o t u s e d -----
992 8 / 0 14 32 +
993 8 / 1 17 35 + +
994
995 channel operator register number Bass High Snare Tom Top
996 number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal
997 6 12,15 B6 A6 +
998
999 7 13,16 B7 A7 + + +
1000
1001 8 14,17 B8 A8 + + +
1002
1003*/
1004
1005/* calculate rhythm */
1006
1007static void OPL_CALC_RH( FM_OPL *OPL, OPL_CH *CH, unsigned int noise )
1008{
1009 OPL_SLOT *SLOT;
1010 signed int out;
1011 unsigned int env;
1012
1013
1014 /* Bass Drum (verified on real YM3812):
1015 - depends on the channel 6 'connect' register:
1016 when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out)
1017 when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored
1018 - output sample always is multiplied by 2
1019 */
1020
1021 OPL->phase_modulation = 0;
1022 /* SLOT 1 */
1023 SLOT = &CH[6].SLOT[SLOT1];
1024 env = volume_calc(SLOT);
1025
1026 out = SLOT->op1_out[0] + SLOT->op1_out[1];
1027 SLOT->op1_out[0] = SLOT->op1_out[1];
1028
1029 if (!SLOT->CON)
1030 OPL->phase_modulation = SLOT->op1_out[0];
1031 /* else ignore output of operator 1 */
1032
1033 SLOT->op1_out[1] = 0;
1034 if( env < ENV_QUIET )
1035 {
1036 if (!SLOT->FB)
1037 out = 0;
1038 SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<<SLOT->FB), SLOT->wavetable );
1039 }
1040
1041 /* SLOT 2 */
1042 SLOT++;
1043 env = volume_calc(SLOT);
1044 if( env < ENV_QUIET )
1045 OPL->output[0] += op_calc(SLOT->Cnt, env, OPL->phase_modulation, SLOT->wavetable) * 2;
1046
1047
1048 /* Phase generation is based on: */
1049 /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 (same combination as TOP CYMBAL but different output phases) */
1050 /* SD (16) channel 7->slot 1 */
1051 /* TOM (14) channel 8->slot 1 */
1052 /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 (same combination as HIGH HAT but different output phases) */
1053
1054 /* Envelope generation based on: */
1055 /* HH channel 7->slot1 */
1056 /* SD channel 7->slot2 */
1057 /* TOM channel 8->slot1 */
1058 /* TOP channel 8->slot2 */
1059
1060
1061 /* The following formulas can be well optimized.
1062 I leave them in direct form for now (in case I've missed something).
1063 */
1064
1065 /* High Hat (verified on real YM3812) */
1066 env = volume_calc(SLOT7_1);
1067 if( env < ENV_QUIET )
1068 {
1069 /* high hat phase generation:
1070 phase = d0 or 234 (based on frequency only)
1071 phase = 34 or 2d0 (based on noise)
1072 */
1073
1074 /* base frequency derived from operator 1 in channel 7 */
1075 unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1;
1076 unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1;
1077 unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1;
1078
1079 unsigned char res1 = (bit2 ^ bit7) | bit3;
1080
1081 /* when res1 = 0 phase = 0x000 | 0xd0; */
1082 /* when res1 = 1 phase = 0x200 | (0xd0>>2); */
1083 UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0;
1084
1085 /* enable gate based on frequency of operator 2 in channel 8 */
1086 unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1;
1087 unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1;
1088
1089 unsigned char res2 = (bit3e ^ bit5e);
1090
1091 /* when res2 = 0 pass the phase from calculation above (res1); */
1092 /* when res2 = 1 phase = 0x200 | (0xd0>>2); */
1093 if (res2)
1094 phase = (0x200|(0xd0>>2));
1095
1096
1097 /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */
1098 /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */
1099 if (phase&0x200)
1100 {
1101 if (noise)
1102 phase = 0x200|0xd0;
1103 }
1104 else
1105 /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */
1106 /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */
1107 {
1108 if (noise)
1109 phase = 0xd0>>2;
1110 }
1111
1112 OPL->output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT7_1->wavetable) * 2;
1113 }
1114
1115 /* Snare Drum (verified on real YM3812) */
1116 env = volume_calc(SLOT7_2);
1117 if( env < ENV_QUIET )
1118 {
1119 /* base frequency derived from operator 1 in channel 7 */
1120 unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1;
1121
1122 /* when bit8 = 0 phase = 0x100; */
1123 /* when bit8 = 1 phase = 0x200; */
1124 UINT32 phase = bit8 ? 0x200 : 0x100;
1125
1126 /* Noise bit XOR'es phase by 0x100 */
1127 /* when noisebit = 0 pass the phase from calculation above */
1128 /* when noisebit = 1 phase ^= 0x100; */
1129 /* in other words: phase ^= (noisebit<<8); */
1130 if (noise)
1131 phase ^= 0x100;
1132
1133 OPL->output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT7_2->wavetable) * 2;
1134 }
1135
1136 /* Tom Tom (verified on real YM3812) */
1137 env = volume_calc(SLOT8_1);
1138 if( env < ENV_QUIET )
1139 OPL->output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2;
1140
1141 /* Top Cymbal (verified on real YM3812) */
1142 env = volume_calc(SLOT8_2);
1143 if( env < ENV_QUIET )
1144 {
1145 /* base frequency derived from operator 1 in channel 7 */
1146 unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1;
1147 unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1;
1148 unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1;
1149
1150 unsigned char res1 = (bit2 ^ bit7) | bit3;
1151
1152 /* when res1 = 0 phase = 0x000 | 0x100; */
1153 /* when res1 = 1 phase = 0x200 | 0x100; */
1154 UINT32 phase = res1 ? 0x300 : 0x100;
1155
1156 /* enable gate based on frequency of operator 2 in channel 8 */
1157 unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1;
1158 unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1;
1159
1160 unsigned char res2 = (bit3e ^ bit5e);
1161 /* when res2 = 0 pass the phase from calculation above (res1); */
1162 /* when res2 = 1 phase = 0x200 | 0x100; */
1163 if (res2)
1164 phase = 0x300;
1165
1166 OPL->output[0] += op_calc(phase<<FREQ_SH, env, 0, SLOT8_2->wavetable) * 2;
1167 }
1168}
1169
1170
1171/* generic table initialize */
1172static int init_tables(void)
1173{
1174 signed int i,x;
1175 signed int n;
1176 double o,m;
1177
1178
1179 for (x=0; x<TL_RES_LEN; x++)
1180 {
1181 m = (1<<16) / pow(2, (x+1) * (ENV_STEP/4.0) / 8.0);
1182 m = floor(m);
1183
1184 /* we never reach (1<<16) here due to the (x+1) */
1185 /* result fits within 16 bits at maximum */
1186
1187 n = (int)m; /* 16 bits here */
1188 n >>= 4; /* 12 bits here */
1189 if (n&1) /* round to nearest */
1190 n = (n>>1)+1;
1191 else
1192 n = n>>1;
1193 /* 11 bits here (rounded) */
1194 n <<= 1; /* 12 bits here (as in real chip) */
1195 tl_tab[ x*2 + 0 ] = n;
1196 tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ];
1197
1198 for (i=1; i<12; i++)
1199 {
1200 tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i;
1201 tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ];
1202 }
1203#if 0
1204 logerror("tl %04i", x*2);
1205 for (i=0; i<12; i++)
1206 logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] );
1207 logerror("\n");
1208#endif
1209 }
1210 /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
1211
1212
1213 for (i=0; i<SIN_LEN; i++)
1214 {
1215 /* non-standard sinus */
1216 m = sin( ((i*2)+1) * M_PI / SIN_LEN ); /* checked against the real chip */
1217
1218 /* we never reach zero here due to ((i*2)+1) */
1219
1220 if (m>0.0)
1221 o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */
1222 else
1223 o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */
1224
1225 o = o / (ENV_STEP/4);
1226
1227 n = (int)(2.0*o);
1228 if (n&1) /* round to nearest */
1229 n = (n>>1)+1;
1230 else
1231 n = n>>1;
1232
1233 sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
1234
1235 /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/
1236 }
1237
1238 for (i=0; i<SIN_LEN; i++)
1239 {
1240 /* waveform 1: __ __ */
1241 /* / \____/ \____*/
1242 /* output only first half of the sinus waveform (positive one) */
1243
1244 if (i & (1<<(SIN_BITS-1)) )
1245 sin_tab[1*SIN_LEN+i] = TL_TAB_LEN;
1246 else
1247 sin_tab[1*SIN_LEN+i] = sin_tab[i];
1248
1249 /* waveform 2: __ __ __ __ */
1250 /* / \/ \/ \/ \*/
1251 /* abs(sin) */
1252
1253 sin_tab[2*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>1) ];
1254
1255 /* waveform 3: _ _ _ _ */
1256 /* / |_/ |_/ |_/ |_*/
1257 /* abs(output only first quarter of the sinus waveform) */
1258
1259 if (i & (1<<(SIN_BITS-2)) )
1260 sin_tab[3*SIN_LEN+i] = TL_TAB_LEN;
1261 else
1262 sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)];
1263
1264 /*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]] );
1265 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]] );
1266 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]] );*/
1267 }
1268 /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/
1269
1270
1271#ifdef SAVE_SAMPLE
1272 sample[0]=fopen("sampsum.pcm","wb");
1273#endif
1274
1275 return 1;
1276}
1277
1278static void OPLCloseTable( void )
1279{
1280#ifdef SAVE_SAMPLE
1281 fclose(sample[0]);
1282#endif
1283}
1284
1285
1286
1287static void OPL_initalize(FM_OPL *OPL)
1288{
1289 int i;
1290
1291 /* frequency base */
1292 OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0;
1293#if 0
1294 OPL->rate = (double)OPL->clock / 72.0;
1295 OPL->freqbase = 1.0;
1296#endif
1297
1298 /*logerror("freqbase=%f\n", OPL->freqbase);*/
1299
1300 /* Timer base time */
1301 OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 );
1302
1303 /* make fnumber -> increment counter table */
1304 for( i=0 ; i < 1024 ; i++ )
1305 {
1306 /* opn phase increment counter = 20bit */
1307 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 */
1308#if 0
1309 logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n",
1310 i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 );
1311#endif
1312 }
1313
1314#if 0
1315 for( i=0 ; i < 16 ; i++ )
1316 {
1317 logerror("FMOPL.C: sl_tab[%i] = %08x\n",
1318 i, sl_tab[i] );
1319 }
1320 for( i=0 ; i < 8 ; i++ )
1321 {
1322 int j;
1323 logerror("FMOPL.C: ksl_tab[oct=%2i] =",i);
1324 for (j=0; j<16; j++)
1325 {
1326 logerror("%08x ", (UINT32)(ksl_tab[i*16+j]) );
1327 }
1328 logerror("\n");
1329 }
1330#endif
1331
1332
1333 /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */
1334 /* One entry from LFO_AM_TABLE lasts for 64 samples */
1335 OPL->lfo_am_inc = (UINT32) ((1.0 / 64.0 ) * (1<<LFO_SH) * OPL->freqbase);
1336
1337 /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */
1338 OPL->lfo_pm_inc = (UINT32) ((1.0 / 1024.0) * (1<<LFO_SH) * OPL->freqbase);
1339
1340 /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/
1341
1342 /* Noise generator: a step takes 1 sample */
1343 OPL->noise_f = (UINT32) ((1.0 / 1.0) * (1<<FREQ_SH) * OPL->freqbase);
1344
1345 OPL->eg_timer_add = (UINT32) ((1<<EG_SH) * OPL->freqbase);
1346 OPL->eg_timer_overflow = ( 1 ) * (1<<EG_SH);
1347 /*logerror("OPLinit eg_timer_add=%8x eg_timer_overflow=%8x\n", OPL->eg_timer_add, OPL->eg_timer_overflow);*/
1348
1349}
1350
1351static void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set)
1352{
1353 if( !SLOT->key )
1354 {
1355 /* restart Phase Generator */
1356 SLOT->Cnt = 0;
1357 /* phase -> Attack */
1358 SLOT->state = EG_ATT;
1359 }
1360 SLOT->key |= key_set;
1361}
1362
1363static void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr)
1364{
1365 if( SLOT->key )
1366 {
1367 SLOT->key &= key_clr;
1368
1369 if( !SLOT->key )
1370 {
1371 /* phase -> Release */
1372 if (SLOT->state>EG_REL)
1373 SLOT->state = EG_REL;
1374 }
1375 }
1376}
1377
1378/* update phase increment counter of operator (also update the EG rates if necessary) */
1379static void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
1380{
1381 int ksr;
1382
1383 /* (frequency) phase increment counter */
1384 SLOT->Incr = CH->fc * SLOT->mul;
1385 ksr = CH->kcode >> SLOT->KSR;
1386
1387 if( SLOT->ksr != ksr )
1388 {
1389 SLOT->ksr = ksr;
1390
1391 /* calculate envelope generator rates */
1392 if ((SLOT->ar + SLOT->ksr) < 16+62)
1393 {
1394 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1395 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1396 }
1397 else
1398 {
1399 SLOT->eg_sh_ar = 0;
1400 SLOT->eg_sel_ar = 13*RATE_STEPS;
1401 }
1402 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1403 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1404 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1405 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1406 }
1407}
1408
1409/* set multi,am,vib,EG-TYP,KSR,mul */
1410static void set_mul(FM_OPL *OPL,int slot,int v)
1411{
1412 OPL_CH *CH = &OPL->P_CH[slot/2];
1413 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
1414
1415 SLOT->mul = mul_tab[v&0x0f];
1416 SLOT->KSR = (v&0x10) ? 0 : 2;
1417 SLOT->eg_type = (v&0x20);
1418 SLOT->vib = (v&0x40);
1419 SLOT->AMmask = (v&0x80) ? ~0 : 0;
1420 CALC_FCSLOT(CH,SLOT);
1421}
1422
1423/* set ksl & tl */
1424static void set_ksl_tl(FM_OPL *OPL,int slot,int v)
1425{
1426#if 0
1427 OPL_CH *CH = &OPL->P_CH[slot/2];
1428 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
1429
1430 SLOT->ksl = ksl_shift[v >> 6];
1431 SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */
1432
1433 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
1434#else
1435 OPL_CH *CH = &OPL->P_CH[slot/2];
1436 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
1437 int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */
1438
1439 SLOT->ksl = ksl ? 3-ksl : 31;
1440 SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */
1441
1442 SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
1443#endif
1444}
1445
1446/* set attack rate & decay rate */
1447static void set_ar_dr(FM_OPL *OPL,int slot,int v)
1448{
1449 OPL_CH *CH = &OPL->P_CH[slot/2];
1450 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
1451
1452 SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0;
1453
1454 if ((SLOT->ar + SLOT->ksr) < 16+62)
1455 {
1456 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1457 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1458 }
1459 else
1460 {
1461 SLOT->eg_sh_ar = 0;
1462 SLOT->eg_sel_ar = 13*RATE_STEPS;
1463 }
1464
1465 SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
1466 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1467 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1468}
1469
1470/* set sustain level & release rate */
1471static void set_sl_rr(FM_OPL *OPL,int slot,int v)
1472{
1473 OPL_CH *CH = &OPL->P_CH[slot/2];
1474 OPL_SLOT *SLOT = &CH->SLOT[slot&1];
1475
1476 SLOT->sl = sl_tab[ v>>4 ];
1477
1478 SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0;
1479 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1480 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1481}
1482
1483
1484/* write a value v to register r on OPL chip */
1485static void OPLWriteReg(FM_OPL *OPL, int r, int v)
1486{
1487 OPL_CH *CH;
1488 int slot;
1489 int block_fnum;
1490
1491
1492 /* adjust bus to 8 bits */
1493 r &= 0xff;
1494 v &= 0xff;
1495
1496 if (LOG_CYM_FILE && (cymfile) && (r!=0) )
1497 {
1498 fprintf(cymfile, "%02x = %02x\n", r, v);
1499 }
1500
1501
1502 switch(r&0xe0)
1503 {
1504 case 0x00: /* 00-1f:control */
1505 switch(r&0x1f)
1506 {
1507 case 0x01: /* waveform select enable */
1508 if(OPL->type&OPL_TYPE_WAVESEL)
1509 {
1510 OPL->wavesel = v&0x20;
1511 /* do not change the waveform previously selected */
1512 }
1513 break;
1514 case 0x02: /* Timer 1 */
1515 OPL->T[0] = (256-v)*4;
1516 break;
1517 case 0x03: /* Timer 2 */
1518 OPL->T[1] = (256-v)*16;
1519 break;
1520 case 0x04: /* IRQ clear / mask and Timer enable */
1521 if(v&0x80)
1522 { /* IRQ flag clear */
1523 OPL_STATUS_RESET(OPL,0x7f-0x08); /* don't reset BFRDY flag or we will have to call deltat module to set the flag */
1524 }
1525 else
1526 { /* set IRQ mask ,timer enable*/
1527 UINT8 st1 = v&1;
1528 UINT8 st2 = (v>>1)&1;
1529
1530 /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
1531 OPL_STATUS_RESET(OPL, v & (0x78-0x08) );
1532 OPL_STATUSMASK_SET(OPL, (~v) & 0x78 );
1533
1534 /* timer 2 */
1535 if(OPL->st[1] != st2)
1536 {
1537 double period = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
1538 //double period = st2 ? (OPL->TimerBase * OPL->T[1]) : 0;
1539 OPL->st[1] = st2;
1540 if (OPL->timer_handler) (OPL->timer_handler)(1,period);
1541 }
1542 /* timer 1 */
1543 if(OPL->st[0] != st1)
1544 {
1545 double period = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
1546 //double period = st1 ? (OPL->TimerBase * OPL->T[0]) : 0;
1547 OPL->st[0] = st1;
1548 if (OPL->timer_handler) (OPL->timer_handler)(0,period);
1549 }
1550 }
1551 break;
1552#if BUILD_Y8950
1553 case 0x06: /* Key Board OUT */
1554 if(OPL->type&OPL_TYPE_KEYBOARD)
1555 {
1556 if(OPL->keyboardhandler_w)
1557 OPL->keyboardhandler_w(OPL->keyboard_param,v);
1558 else
1559 {
1560 //OPL->device->logerror("Y8950: write unmapped KEYBOARD port\n");
1561 }
1562 }
1563 break;
1564 case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
1565 if(OPL->type&OPL_TYPE_ADPCM)
1566 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
1567 break;
1568#endif
1569 case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
1570 OPL->mode = v;
1571#if BUILD_Y8950
1572 if(OPL->type&OPL_TYPE_ADPCM)
1573 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); /* mask 4 LSBs in register 08 for DELTA-T unit */
1574#endif
1575 break;
1576
1577#if BUILD_Y8950
1578 case 0x09: /* START ADD */
1579 case 0x0a:
1580 case 0x0b: /* STOP ADD */
1581 case 0x0c:
1582 case 0x0d: /* PRESCALE */
1583 case 0x0e:
1584 case 0x0f: /* ADPCM data write */
1585 case 0x10: /* DELTA-N */
1586 case 0x11: /* DELTA-N */
1587 case 0x12: /* ADPCM volume */
1588 if(OPL->type&OPL_TYPE_ADPCM)
1589 YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
1590 break;
1591
1592 case 0x15: /* DAC data high 8 bits (F7,F6...F2) */
1593 case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */
1594 case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */
1595 //OPL->device->logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n",r,v);
1596 break;
1597
1598 case 0x18: /* I/O CTRL (Direction) */
1599 if(OPL->type&OPL_TYPE_IO)
1600 OPL->portDirection = v&0x0f;
1601 break;
1602 case 0x19: /* I/O DATA */
1603 if(OPL->type&OPL_TYPE_IO)
1604 {
1605 OPL->portLatch = v;
1606 if(OPL->porthandler_w)
1607 OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
1608 }
1609 break;
1610#endif
1611 default:
1612 //OPL->device->logerror("FMOPL.C: write to unknown register: %02x\n",r);
1613 break;
1614 }
1615 break;
1616 case 0x20: /* am ON, vib ON, ksr, eg_type, mul */
1617 slot = slot_array[r&0x1f];
1618 if(slot < 0) return;
1619 set_mul(OPL,slot,v);
1620 break;
1621 case 0x40:
1622 slot = slot_array[r&0x1f];
1623 if(slot < 0) return;
1624 set_ksl_tl(OPL,slot,v);
1625 break;
1626 case 0x60:
1627 slot = slot_array[r&0x1f];
1628 if(slot < 0) return;
1629 set_ar_dr(OPL,slot,v);
1630 break;
1631 case 0x80:
1632 slot = slot_array[r&0x1f];
1633 if(slot < 0) return;
1634 set_sl_rr(OPL,slot,v);
1635 break;
1636 case 0xa0:
1637 if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */
1638 {
1639 OPL->lfo_am_depth = v & 0x80;
1640 OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0;
1641
1642 OPL->rhythm = v&0x3f;
1643
1644 if(OPL->rhythm&0x20)
1645 {
1646 /* BD key on/off */
1647 if(v&0x10)
1648 {
1649 FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2);
1650 FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2);
1651 }
1652 else
1653 {
1654 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2);
1655 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2);
1656 }
1657 /* HH key on/off */
1658 if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2);
1659 else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2);
1660 /* SD key on/off */
1661 if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2);
1662 else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2);
1663 /* TOM key on/off */
1664 if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2);
1665 else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2);
1666 /* TOP-CY key on/off */
1667 if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2);
1668 else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2);
1669 }
1670 else
1671 {
1672 /* BD key off */
1673 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2);
1674 FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2);
1675 /* HH key off */
1676 FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2);
1677 /* SD key off */
1678 FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2);
1679 /* TOM key off */
1680 FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2);
1681 /* TOP-CY off */
1682 FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2);
1683 }
1684 return;
1685 }
1686 /* keyon,block,fnum */
1687 if( (r&0x0f) > 8) return;
1688 CH = &OPL->P_CH[r&0x0f];
1689 if(!(r&0x10))
1690 { /* a0-a8 */
1691 block_fnum = (CH->block_fnum&0x1f00) | v;
1692 }
1693 else
1694 { /* b0-b8 */
1695 block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
1696
1697 if(v&0x20)
1698 {
1699 FM_KEYON (&CH->SLOT[SLOT1], 1);
1700 FM_KEYON (&CH->SLOT[SLOT2], 1);
1701 }
1702 else
1703 {
1704 FM_KEYOFF(&CH->SLOT[SLOT1],~1);
1705 FM_KEYOFF(&CH->SLOT[SLOT2],~1);
1706 }
1707 }
1708 /* update */
1709 if(CH->block_fnum != (UINT32) block_fnum)
1710 {
1711 UINT8 block = block_fnum >> 10;
1712
1713 CH->block_fnum = block_fnum;
1714
1715 CH->ksl_base = (UINT32)(ksl_tab[block_fnum>>6]);
1716 CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block);
1717
1718 /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */
1719 CH->kcode = (CH->block_fnum&0x1c00)>>9;
1720
1721 /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */
1722 /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */
1723 /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */
1724 if (OPL->mode&0x40)
1725 CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */
1726 else
1727 CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */
1728
1729 /* refresh Total Level in both SLOTs of this channel */
1730 CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl);
1731 CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl);
1732
1733 /* refresh frequency counter in both SLOTs of this channel */
1734 CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
1735 CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
1736 }
1737 break;
1738 case 0xc0:
1739 /* FB,C */
1740 if( (r&0x0f) > 8) return;
1741 CH = &OPL->P_CH[r&0x0f];
1742 CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0;
1743 CH->SLOT[SLOT1].CON = v&1;
1744 CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &OPL->output[0] : &OPL->phase_modulation;
1745 break;
1746 case 0xe0: /* waveform select */
1747 /* simply ignore write to the waveform select register if selecting not enabled in test register */
1748 if(OPL->wavesel)
1749 {
1750 slot = slot_array[r&0x1f];
1751 if(slot < 0) return;
1752 CH = &OPL->P_CH[slot/2];
1753
1754 CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN;
1755 }
1756 break;
1757 }
1758}
1759
1760static TIMER_CALLBACK( cymfile_callback )
1761{
1762 if (cymfile)
1763 {
1764 //fputc( (unsigned char)0, cymfile );
1765 }
1766}
1767
1768/* lock/unlock for common table */
1769static int OPL_LockTable(device_t *device)
1770{
1771 num_lock++;
1772 if(num_lock>1) return 0;
1773
1774 /* first time */
1775
1776 /* allocate total level table (128kb space) */
1777 if( !init_tables() )
1778 {
1779 num_lock--;
1780 return -1;
1781 }
1782
1783 if (LOG_CYM_FILE)
1784 {
1785 cymfile = fopen("/3812_.cym","w");
1786 if (cymfile)
1787 {
1788 //device->machine().scheduler().timer_pulse ( double::from_hz(110), FUNC(cymfile_callback)); /*110 Hz pulse timer*/
1789 }
1790 else
1791 {
1792 //device->logerror("Could not create file 3812_.cym\n");
1793 }
1794 }
1795
1796 return 0;
1797}
1798
1799static void OPL_UnLockTable(void)
1800{
1801 if(num_lock) num_lock--;
1802 if(num_lock) return;
1803
1804 /* last time */
1805
1806 OPLCloseTable();
1807
1808 if (cymfile)
1809 fclose (cymfile);
1810 cymfile = NULL;
1811}
1812
1813static void OPLResetChip(FM_OPL *OPL)
1814{
1815 int c,s;
1816 int i;
1817
1818 OPL->eg_timer = 0;
1819 OPL->eg_cnt = 0;
1820
1821 OPL->noise_rng = 1; /* noise shift register */
1822 OPL->mode = 0; /* normal mode */
1823 OPL_STATUS_RESET(OPL,0x7f);
1824
1825 /* reset with register write */
1826 OPLWriteReg(OPL,0x01,0); /* wavesel disable */
1827 OPLWriteReg(OPL,0x02,0); /* Timer1 */
1828 OPLWriteReg(OPL,0x03,0); /* Timer2 */
1829 OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
1830 for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
1831
1832 /* reset operator parameters */
1833 for( c = 0 ; c < 9 ; c++ )
1834 {
1835 OPL_CH *CH = &OPL->P_CH[c];
1836 for(s = 0 ; s < 2 ; s++ )
1837 {
1838 /* wave table */
1839 CH->SLOT[s].wavetable = 0;
1840 CH->SLOT[s].state = EG_OFF;
1841 CH->SLOT[s].volume = MAX_ATT_INDEX;
1842 }
1843 }
1844#if BUILD_Y8950
1845 if(OPL->type&OPL_TYPE_ADPCM)
1846 {
1847 YM_DELTAT *DELTAT = OPL->deltat;
1848
1849 DELTAT->freqbase = OPL->freqbase;
1850 DELTAT->output_pointer = &OPL->output_deltat[0];
1851 DELTAT->portshift = 5;
1852 DELTAT->output_range = 1<<23;
1853 YM_DELTAT_ADPCM_Reset(DELTAT,0,YM_DELTAT_EMULATION_MODE_NORMAL,OPL->device);
1854 }
1855#endif
1856}
1857
1858
1859static void OPL_postload(FM_OPL *OPL)
1860{
1861 int slot, ch;
1862
1863 for( ch=0 ; ch < 9 ; ch++ )
1864 {
1865 OPL_CH *CH = &OPL->P_CH[ch];
1866
1867 /* Look up key scale level */
1868 UINT32 block_fnum = CH->block_fnum;
1869 CH->ksl_base = (UINT32)(ksl_tab[block_fnum >> 6]);
1870 CH->fc = OPL->fn_tab[block_fnum & 0x03ff] >> (7 - (block_fnum >> 10));
1871
1872 for( slot=0 ; slot < 2 ; slot++ )
1873 {
1874 OPL_SLOT *SLOT = &CH->SLOT[slot];
1875
1876 /* Calculate key scale rate */
1877 SLOT->ksr = CH->kcode >> SLOT->KSR;
1878
1879 /* Calculate attack, decay and release rates */
1880 if ((SLOT->ar + SLOT->ksr) < 16+62)
1881 {
1882 SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ];
1883 SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ];
1884 }
1885 else
1886 {
1887 SLOT->eg_sh_ar = 0;
1888 SLOT->eg_sel_ar = 13*RATE_STEPS;
1889 }
1890 SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ];
1891 SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ];
1892 SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ];
1893 SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ];
1894
1895 /* Calculate phase increment */
1896 SLOT->Incr = CH->fc * SLOT->mul;
1897
1898 /* Total level */
1899 SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl);
1900
1901 /* Connect output */
1902 SLOT->connect1 = SLOT->CON ? &OPL->output[0] : &OPL->phase_modulation;
1903 }
1904 }
1905#if BUILD_Y8950
1906 if ( (OPL->type & OPL_TYPE_ADPCM) && (OPL->deltat) )
1907 {
1908 // We really should call the postlod function for the YM_DELTAT, but it's hard without registers
1909 // (see the way the YM2610 does it)
1910 //YM_DELTAT_postload(OPL->deltat, REGS);
1911 }
1912#endif
1913}
1914
1915
1916static void OPLsave_state_channel(device_t *device, OPL_CH *CH)
1917{
1918}
1919
1920
1921/* Register savestate for a virtual YM3812/YM3526Y8950 */
1922
1923static void OPL_save_state(FM_OPL *OPL, device_t *device)
1924{
1925}
1926
1927
1928/* Create one of virtual YM3812/YM3526/Y8950 */
1929/* 'clock' is chip clock in Hz */
1930/* 'rate' is sampling rate */
1931static FM_OPL *OPLCreate(device_t *device, UINT32 clock, UINT32 rate, int type)
1932{
1933 char *ptr;
1934 FM_OPL *OPL;
1935 int state_size;
1936
1937 if (OPL_LockTable(device) == -1) return NULL;
1938
1939 /* calculate OPL state size */
1940 state_size = sizeof(FM_OPL);
1941
1942#if BUILD_Y8950
1943 if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
1944#endif
1945
1946 /* allocate memory block */
1947 ptr = malloc(state_size);
1948
1949 if(!ptr)
1950 return NULL;
1951
1952 memset(ptr, 0, state_size);
1953
1954 OPL = (FM_OPL *)ptr;
1955
1956 /* GCC behaves weirdly... check that it's not acting up */
1957
1958 if((UINT32)OPL & 3 == 0)
1959 printf("OPL is word-aligned");
1960 if((UINT32)(OPL->output) & 3 == 0)
1961 printf("output is word-aligned");
1962
1963 ptr += sizeof(FM_OPL);
1964
1965#if BUILD_Y8950
1966 if (type&OPL_TYPE_ADPCM)
1967 {
1968 OPL->deltat = (YM_DELTAT *)ptr;
1969 }
1970 ptr += sizeof(YM_DELTAT);
1971#endif
1972
1973 OPL->device = device;
1974 OPL->type = type;
1975 OPL->clock = clock;
1976 OPL->rate = rate;
1977
1978 /* init global tables */
1979 OPL_initalize(OPL);
1980
1981 return OPL;
1982}
1983
1984/* Destroy one of virtual YM3812 */
1985static void OPLDestroy(FM_OPL *OPL)
1986{
1987 OPL_UnLockTable();
1988 free(OPL);
1989}
1990
1991/* Optional handlers */
1992
1993static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER timer_handler,void *param)
1994{
1995 OPL->timer_handler = timer_handler;
1996 OPL->TimerParam = param;
1997}
1998static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,void *param)
1999{
2000 OPL->IRQHandler = IRQHandler;
2001 OPL->IRQParam = param;
2002}
2003static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,void *param)
2004{
2005 OPL->UpdateHandler = UpdateHandler;
2006 OPL->UpdateParam = param;
2007}
2008
2009static int OPLWrite(FM_OPL *OPL,int a,int v)
2010{
2011 if( !(a&1) )
2012 { /* address port */
2013 OPL->address = v & 0xff;
2014 }
2015 else
2016 { /* data port */
2017 if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
2018 OPLWriteReg(OPL,OPL->address,v);
2019 }
2020 return OPL->status>>7;
2021}
2022
2023static unsigned char OPLRead(FM_OPL *OPL,int a)
2024{
2025 if( !(a&1) )
2026 {
2027 /* status port */
2028
2029#if BUILD_Y8950
2030
2031 if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */
2032 {
2033 return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1);
2034 }
2035
2036#endif
2037
2038 /* OPL and OPL2 */
2039 return OPL->status & (OPL->statusmask|0x80);
2040 }
2041
2042#if BUILD_Y8950
2043 /* data port */
2044 switch(OPL->address)
2045 {
2046 case 0x05: /* KeyBoard IN */
2047 if(OPL->type&OPL_TYPE_KEYBOARD)
2048 {
2049 if(OPL->keyboardhandler_r)
2050 return OPL->keyboardhandler_r(OPL->keyboard_param);
2051 else
2052 OPL->device->logerror("Y8950: read unmapped KEYBOARD port\n");
2053 }
2054 return 0;
2055
2056 case 0x0f: /* ADPCM-DATA */
2057 if(OPL->type&OPL_TYPE_ADPCM)
2058 {
2059 UINT8 val;
2060
2061 val = YM_DELTAT_ADPCM_Read(OPL->deltat);
2062 /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/
2063 return val;
2064 }
2065 return 0;
2066
2067 case 0x19: /* I/O DATA */
2068 if(OPL->type&OPL_TYPE_IO)
2069 {
2070 if(OPL->porthandler_r)
2071 return OPL->porthandler_r(OPL->port_param);
2072 else
2073 OPL->device->logerror("Y8950:read unmapped I/O port\n");
2074 }
2075 return 0;
2076 case 0x1a: /* PCM-DATA */
2077 if(OPL->type&OPL_TYPE_ADPCM)
2078 {
2079 OPL->device->logerror("Y8950 A/D convertion is accessed but not implemented !\n");
2080 return 0x80; /* 2's complement PCM data - result from A/D convertion */
2081 }
2082 return 0;
2083 }
2084#endif
2085
2086 return 0xff;
2087}
2088
2089/* CSM Key Controll */
2090static void CSMKeyControll(OPL_CH *CH)
2091{
2092 FM_KEYON (&CH->SLOT[SLOT1], 4);
2093 FM_KEYON (&CH->SLOT[SLOT2], 4);
2094
2095 /* The key off should happen exactly one sample later - not implemented correctly yet */
2096
2097 FM_KEYOFF(&CH->SLOT[SLOT1], ~4);
2098 FM_KEYOFF(&CH->SLOT[SLOT2], ~4);
2099}
2100
2101
2102static int OPLTimerOver(FM_OPL *OPL,int c)
2103{
2104 if( c )
2105 { /* Timer B */
2106 OPL_STATUS_SET(OPL,0x20);
2107 }
2108 else
2109 { /* Timer A */
2110 OPL_STATUS_SET(OPL,0x40);
2111 /* CSM mode key,TL controll */
2112 if( OPL->mode & 0x80 )
2113 { /* CSM mode total level latch and auto key on */
2114 int ch;
2115 if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
2116 for(ch=0; ch<9; ch++)
2117 CSMKeyControll( &OPL->P_CH[ch] );
2118 }
2119 }
2120 /* reload timer */
2121 if (OPL->timer_handler) (OPL->timer_handler)(c,OPL->TimerBase * OPL->T[c]);
2122 return OPL->status>>7;
2123}
2124
2125
2126#define MAX_OPL_CHIPS 2
2127
2128
2129#if (BUILD_YM3812)
2130
2131void * YM3812Init(device_t *device, UINT32 clock, UINT32 rate)
2132{
2133 /* emulator create */
2134 FM_OPL *YM3812 = OPLCreate(device,clock,rate,OPL_TYPE_YM3812);
2135 if (YM3812)
2136 {
2137 OPL_save_state(YM3812, device);
2138 YM3812ResetChip(YM3812);
2139 }
2140 return YM3812;
2141}
2142
2143void YM3812Shutdown(void *chip)
2144{
2145 FM_OPL *YM3812 = (FM_OPL *)chip;
2146
2147 /* emulator shutdown */
2148 OPLDestroy(YM3812);
2149}
2150void YM3812ResetChip(void *chip)
2151{
2152 FM_OPL *YM3812 = (FM_OPL *)chip;
2153 OPLResetChip(YM3812);
2154}
2155
2156int YM3812Write(void *chip, int a, int v)
2157{
2158 FM_OPL *YM3812 = (FM_OPL *)chip;
2159
2160 OPLWriteReg(YM3812, a, v);
2161 return (YM3812->status>>7);
2162
2163 // technically correct, but breaks Wolf4SDL - FW19
2164 //return OPLWrite(YM3812, a, v);
2165}
2166
2167unsigned char YM3812Read(void *chip, int a)
2168{
2169 FM_OPL *YM3812 = (FM_OPL *)chip;
2170 /* YM3812 always returns bit2 and bit1 in HIGH state */
2171 return OPLRead(YM3812, a) | 0x06 ;
2172}
2173int YM3812TimerOver(void *chip, int c)
2174{
2175 FM_OPL *YM3812 = (FM_OPL *)chip;
2176 return OPLTimerOver(YM3812, c);
2177}
2178
2179void YM3812SetTimerHandler(void *chip, OPL_TIMERHANDLER timer_handler, void *param)
2180{
2181 FM_OPL *YM3812 = (FM_OPL *)chip;
2182 OPLSetTimerHandler(YM3812, timer_handler, param);
2183}
2184void YM3812SetIRQHandler(void *chip,OPL_IRQHANDLER IRQHandler,void *param)
2185{
2186 FM_OPL *YM3812 = (FM_OPL *)chip;
2187 OPLSetIRQHandler(YM3812, IRQHandler, param);
2188}
2189void YM3812SetUpdateHandler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param)
2190{
2191 FM_OPL *YM3812 = (FM_OPL *)chip;
2192 OPLSetUpdateHandler(YM3812, UpdateHandler, param);
2193}
2194
2195
2196/*
2197** Generate samples for one of the YM3812's
2198**
2199** 'which' is the virtual YM3812 number
2200** '*buffer' is the output buffer pointer
2201** 'length' is the number of samples that should be generated
2202*/
2203void YM3812UpdateOne(void *chip, OPLSAMPLE *buffer, int length)
2204{
2205 FM_OPL *OPL = (FM_OPL *)chip;
2206 UINT8 rhythm = OPL->rhythm&0x20;
2207 OPLSAMPLE *buf = buffer;
2208 int i;
2209
2210 for( i=0; i < length ; i++ )
2211 {
2212 int lt;
2213
2214 OPL->output[0] = 0;
2215
2216 advance_lfo(OPL);
2217
2218 /* FM part */
2219 OPL_CALC_CH(OPL, &OPL->P_CH[0]);
2220 OPL_CALC_CH(OPL, &OPL->P_CH[1]);
2221 OPL_CALC_CH(OPL, &OPL->P_CH[2]);
2222 OPL_CALC_CH(OPL, &OPL->P_CH[3]);
2223 OPL_CALC_CH(OPL, &OPL->P_CH[4]);
2224 OPL_CALC_CH(OPL, &OPL->P_CH[5]);
2225
2226 if(!rhythm)
2227 {
2228 OPL_CALC_CH(OPL, &OPL->P_CH[6]);
2229 OPL_CALC_CH(OPL, &OPL->P_CH[7]);
2230 OPL_CALC_CH(OPL, &OPL->P_CH[8]);
2231 }
2232 else /* Rhythm part */
2233 {
2234 OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
2235 }
2236
2237 lt = OPL->output[0];
2238
2239 //lt >>= FINAL_SH;
2240 lt <<= 2;
2241
2242 /* limit check */
2243 lt = limit( lt , MAXOUT, MINOUT );
2244
2245#ifdef SAVE_SAMPLE
2246 if (which==0)
2247 {
2248 SAVE_ALL_CHANNELS
2249 }
2250#endif
2251
2252 /* store to sound buffer */
2253 //buf[i] = lt;
2254
2255 buf[i*2] = lt; // stereo version
2256 buf[i*2+1] = lt;
2257
2258 advance(OPL);
2259 }
2260}
2261#endif /* BUILD_YM3812 */
2262
2263// Rockbox: we don't care about the rest.
2264
2265#if (BUILD_YM3526)
2266
2267void *ym3526_init(device_t *device, UINT32 clock, UINT32 rate)
2268{
2269 /* emulator create */
2270 FM_OPL *YM3526 = OPLCreate(device,clock,rate,OPL_TYPE_YM3526);
2271 if (YM3526)
2272 {
2273 OPL_save_state(YM3526, device);
2274 ym3526_reset_chip(YM3526);
2275 }
2276 return YM3526;
2277}
2278
2279void ym3526_shutdown(void *chip)
2280{
2281 FM_OPL *YM3526 = (FM_OPL *)chip;
2282 /* emulator shutdown */
2283 OPLDestroy(YM3526);
2284}
2285void ym3526_reset_chip(void *chip)
2286{
2287 FM_OPL *YM3526 = (FM_OPL *)chip;
2288 OPLResetChip(YM3526);
2289}
2290
2291int ym3526_write(void *chip, int a, int v)
2292{
2293 FM_OPL *YM3526 = (FM_OPL *)chip;
2294 return OPLWrite(YM3526, a, v);
2295}
2296
2297unsigned char ym3526_read(void *chip, int a)
2298{
2299 FM_OPL *YM3526 = (FM_OPL *)chip;
2300 /* YM3526 always returns bit2 and bit1 in HIGH state */
2301 return OPLRead(YM3526, a) | 0x06 ;
2302}
2303int ym3526_timer_over(void *chip, int c)
2304{
2305 FM_OPL *YM3526 = (FM_OPL *)chip;
2306 return OPLTimerOver(YM3526, c);
2307}
2308
2309void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param)
2310{
2311 FM_OPL *YM3526 = (FM_OPL *)chip;
2312 OPLSetTimerHandler(YM3526, timer_handler, param);
2313}
2314void ym3526_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param)
2315{
2316 FM_OPL *YM3526 = (FM_OPL *)chip;
2317 OPLSetIRQHandler(YM3526, IRQHandler, param);
2318}
2319void ym3526_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param)
2320{
2321 FM_OPL *YM3526 = (FM_OPL *)chip;
2322 OPLSetUpdateHandler(YM3526, UpdateHandler, param);
2323}
2324
2325
2326/*
2327** Generate samples for one of the YM3526's
2328**
2329** 'which' is the virtual YM3526 number
2330** '*buffer' is the output buffer pointer
2331** 'length' is the number of samples that should be generated
2332*/
2333void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length)
2334{
2335 FM_OPL *OPL = (FM_OPL *)chip;
2336 UINT8 rhythm = OPL->rhythm&0x20;
2337 OPLSAMPLE *buf = buffer;
2338 int i;
2339
2340 for( i=0; i < length ; i++ )
2341 {
2342 int lt;
2343
2344 OPL->output[0] = 0;
2345
2346 advance_lfo(OPL);
2347
2348 /* FM part */
2349 OPL_CALC_CH(OPL, &OPL->P_CH[0]);
2350 OPL_CALC_CH(OPL, &OPL->P_CH[1]);
2351 OPL_CALC_CH(OPL, &OPL->P_CH[2]);
2352 OPL_CALC_CH(OPL, &OPL->P_CH[3]);
2353 OPL_CALC_CH(OPL, &OPL->P_CH[4]);
2354 OPL_CALC_CH(OPL, &OPL->P_CH[5]);
2355
2356 if(!rhythm)
2357 {
2358 OPL_CALC_CH(OPL, &OPL->P_CH[6]);
2359 OPL_CALC_CH(OPL, &OPL->P_CH[7]);
2360 OPL_CALC_CH(OPL, &OPL->P_CH[8]);
2361 }
2362 else /* Rhythm part */
2363 {
2364 OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
2365 }
2366
2367 lt = OPL->output[0];
2368
2369 lt >>= FINAL_SH;
2370
2371 /* limit check */
2372 lt = limit( lt , MAXOUT, MINOUT );
2373
2374#ifdef SAVE_SAMPLE
2375 if (which==0)
2376 {
2377 SAVE_ALL_CHANNELS
2378 }
2379#endif
2380
2381 /* store to sound buffer */
2382 buf[i] = lt;
2383
2384 advance(OPL);
2385 }
2386
2387}
2388#endif /* BUILD_YM3526 */
2389
2390
2391
2392
2393#if BUILD_Y8950
2394
2395static void Y8950_deltat_status_set(void *chip, UINT8 changebits)
2396{
2397 FM_OPL *Y8950 = (FM_OPL *)chip;
2398 OPL_STATUS_SET(Y8950, changebits);
2399}
2400static void Y8950_deltat_status_reset(void *chip, UINT8 changebits)
2401{
2402 FM_OPL *Y8950 = (FM_OPL *)chip;
2403 OPL_STATUS_RESET(Y8950, changebits);
2404}
2405
2406void *y8950_init(device_t *device, UINT32 clock, UINT32 rate)
2407{
2408 /* emulator create */
2409 FM_OPL *Y8950 = OPLCreate(device,clock,rate,OPL_TYPE_Y8950);
2410 if (Y8950)
2411 {
2412 Y8950->deltat->status_set_handler = Y8950_deltat_status_set;
2413 Y8950->deltat->status_reset_handler = Y8950_deltat_status_reset;
2414 Y8950->deltat->status_change_which_chip = Y8950;
2415 Y8950->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */
2416 Y8950->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */
2417
2418 /*Y8950->deltat->write_time = 10.0 / clock;*/ /* a single byte write takes 10 cycles of main clock */
2419 /*Y8950->deltat->read_time = 8.0 / clock;*/ /* a single byte read takes 8 cycles of main clock */
2420 /* reset */
2421 OPL_save_state(Y8950, device);
2422 y8950_reset_chip(Y8950);
2423 }
2424
2425 return Y8950;
2426}
2427
2428void y8950_shutdown(void *chip)
2429{
2430 FM_OPL *Y8950 = (FM_OPL *)chip;
2431 /* emulator shutdown */
2432 OPLDestroy(Y8950);
2433}
2434void y8950_reset_chip(void *chip)
2435{
2436 FM_OPL *Y8950 = (FM_OPL *)chip;
2437 OPLResetChip(Y8950);
2438}
2439
2440int y8950_write(void *chip, int a, int v)
2441{
2442 FM_OPL *Y8950 = (FM_OPL *)chip;
2443 return OPLWrite(Y8950, a, v);
2444}
2445
2446unsigned char y8950_read(void *chip, int a)
2447{
2448 FM_OPL *Y8950 = (FM_OPL *)chip;
2449 return OPLRead(Y8950, a);
2450}
2451int y8950_timer_over(void *chip, int c)
2452{
2453 FM_OPL *Y8950 = (FM_OPL *)chip;
2454 return OPLTimerOver(Y8950, c);
2455}
2456
2457void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param)
2458{
2459 FM_OPL *Y8950 = (FM_OPL *)chip;
2460 OPLSetTimerHandler(Y8950, timer_handler, param);
2461}
2462void y8950_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param)
2463{
2464 FM_OPL *Y8950 = (FM_OPL *)chip;
2465 OPLSetIRQHandler(Y8950, IRQHandler, param);
2466}
2467void y8950_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param)
2468{
2469 FM_OPL *Y8950 = (FM_OPL *)chip;
2470 OPLSetUpdateHandler(Y8950, UpdateHandler, param);
2471}
2472
2473void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size )
2474{
2475 FM_OPL *OPL = (FM_OPL *)chip;
2476 OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr);
2477 OPL->deltat->memory_size = deltat_mem_size;
2478}
2479
2480/*
2481** Generate samples for one of the Y8950's
2482**
2483** 'which' is the virtual Y8950 number
2484** '*buffer' is the output buffer pointer
2485** 'length' is the number of samples that should be generated
2486*/
2487void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length)
2488{
2489 int i;
2490 FM_OPL *OPL = (FM_OPL *)chip;
2491 UINT8 rhythm = OPL->rhythm&0x20;
2492 YM_DELTAT *DELTAT = OPL->deltat;
2493 OPLSAMPLE *buf = buffer;
2494
2495 for( i=0; i < length ; i++ )
2496 {
2497 int lt;
2498
2499 OPL->output[0] = 0;
2500 OPL->output_deltat[0] = 0;
2501
2502 advance_lfo(OPL);
2503
2504 /* deltaT ADPCM */
2505 if( DELTAT->portstate&0x80 )
2506 YM_DELTAT_ADPCM_CALC(DELTAT);
2507
2508 /* FM part */
2509 OPL_CALC_CH(OPL, &OPL->P_CH[0]);
2510 OPL_CALC_CH(OPL, &OPL->P_CH[1]);
2511 OPL_CALC_CH(OPL, &OPL->P_CH[2]);
2512 OPL_CALC_CH(OPL, &OPL->P_CH[3]);
2513 OPL_CALC_CH(OPL, &OPL->P_CH[4]);
2514 OPL_CALC_CH(OPL, &OPL->P_CH[5]);
2515
2516 if(!rhythm)
2517 {
2518 OPL_CALC_CH(OPL, &OPL->P_CH[6]);
2519 OPL_CALC_CH(OPL, &OPL->P_CH[7]);
2520 OPL_CALC_CH(OPL, &OPL->P_CH[8]);
2521 }
2522 else /* Rhythm part */
2523 {
2524 OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 );
2525 }
2526
2527 lt = OPL->output[0] + (OPL->output_deltat[0]>>11);
2528
2529 lt >>= FINAL_SH;
2530
2531 /* limit check */
2532 lt = limit( lt , MAXOUT, MINOUT );
2533
2534#ifdef SAVE_SAMPLE
2535 if (which==0)
2536 {
2537 SAVE_ALL_CHANNELS
2538 }
2539#endif
2540
2541 /* store to sound buffer */
2542 buf[i] = lt;
2543
2544 advance(OPL);
2545 }
2546
2547}
2548
2549void y8950_set_port_handler(void *chip,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,void * param)
2550{
2551 FM_OPL *OPL = (FM_OPL *)chip;
2552 OPL->porthandler_w = PortHandler_w;
2553 OPL->porthandler_r = PortHandler_r;
2554 OPL->port_param = param;
2555}
2556
2557void y8950_set_keyboard_handler(void *chip,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,void * param)
2558{
2559 FM_OPL *OPL = (FM_OPL *)chip;
2560 OPL->keyboardhandler_w = KeyboardHandler_w;
2561 OPL->keyboardhandler_r = KeyboardHandler_r;
2562 OPL->keyboard_param = param;
2563}
2564
2565#endif