1 #define YM2610B_WARNING
2
3 /* YM2608 rhythm data is PCM ,not an ADPCM */
4 #define YM2608_RHYTHM_PCM
5
6 /*
7 **
8 ** File: fm.c -- software implementation of FM sound generator
9 **
10 ** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
11 **
12 ** Version 0.37
13 **
14 */
15
16 /*
17 **** change log. (hiro-shi) ****
18 ** 08-12-98:
19 ** rename ADPCMA -> ADPCMB, ADPCMB -> ADPCMA
20 ** move ROM limit check.(CALC_CH? -> 2610Write1/2)
21 ** test program (ADPCMB_TEST)
22 ** move ADPCM A/B end check.
23 ** ADPCMB repeat flag(no check)
24 ** change ADPCM volume rate (8->16) (32->48).
25 **
26 ** 09-12-98:
27 ** change ADPCM volume. (8->16, 48->64)
28 ** replace ym2610 ch0/3 (YM-2610B)
29 ** init cur_chip (restart bug fix)
30 ** change ADPCM_SHIFT (10->8) missing bank change 0x4000-0xffff.
31 ** add ADPCM_SHIFT_MASK
32 ** change ADPCMA_DECODE_MIN/MAX.
33 */
34
35 /*
36 no check:
37 YM2608 rhythm sound
38 OPN SSG type envelope (SEG)
39 YM2151 CSM speech mode
40
41 no support:
42 status BUSY flag (everytime not busy)
43 YM2608 status mask (register :0x110)
44 YM2608 RYTHM sound
45 YM2608 PCM memory data access , DELTA-T-ADPCM with PCM port
46 YM2151 CSM speech mode with internal timer
47
48 preliminary :
49 key scale level rate (?)
50 attack rate time rate , curve
51 decay rate time rate , curve
52 self-feedback algorythm
53 YM2610 ADPCM-A mixing level , decode algorythm
54 YM2151 noise mode (CH7.OP4)
55 LFO contoller (YM2612/YM2610/YM2608/YM2151)
56
57 note:
58 OPN OPM
59 fnum fM * 2^20 / (fM/(12*n))
60 TimerOverA ( 12*n)*(1024-NA)/fM 64*(1024-Na)/fM
61 TimerOverB (192*n)*(256-NB)/fM 1024*(256-Nb)/fM
62 output bits 10bit<<3bit 16bit * 2ch (YM3012=10bit<<3bit)
63 sampling rate fFM / (12*priscaler) fM / 64
64 lfo freq ( fM*2^(LFRQ/16) ) / (4295*10^6)
65 */
66
67 /************************************************************************/
68 /* comment of hiro-shi(Hiromitsu Shioya) */
69 /* YM2610(B) = (OPN-B */
70 /* YM2610 : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
71 /* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
72 /************************************************************************/
73
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <string.h>
77 #include <stdarg.h>
78 #include <math.h>
79 #ifndef __RAINE__
80 #include "driver.h" /* use M.A.M.E. */
81 #else
82 #include "deftypes.h" /* use RAINE */
83 #include "support.h" /* use RAINE */
84 #endif
85 #include "ay8910.h"
86 #include "fm.h"
87 #include "osinline.h"
88
89 #ifndef PI
90 #define PI 3.14159265358979323846
91 #endif
92
93 /***** shared function building option ****/
94 #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2612)
95 #define BUILD_OPNB (BUILD_YM2610||BUILD_YM2610B)
96 #define BUILD_FM_ADPCMA (BUILD_YM2608||BUILD_OPNB)
97 #define BUILD_FM_ADPCMB (BUILD_YM2608||BUILD_OPNB)
98 #define BUILD_STEREO (BUILD_YM2608||BUILD_YM2610||BUILD_YM2612||BUILD_YM2151)
99 #define BUILD_LFO (BUILD_YM2608||BUILD_YM2610||BUILD_YM2612||BUILD_YM2151)
100
101 #if BUILD_FM_ADPCMB
102 /* include external DELTA-T ADPCM unit */
103 #include "ymdeltat.h" /* DELTA-T ADPCM UNIT */
104 #define DELTAT_MIXING_LEVEL (4) /* DELTA-T ADPCM MIXING LEVEL */
105 #endif
106
107 #ifdef MAME_FASTSOUND
108 extern int fast_sound;
109 #endif
110
111 /* -------------------- sound quality define selection --------------------- */
112 /* sinwave entries */
113 /* used static memory = SIN_ENT * 4 (byte) */
114 #define SIN_ENT 2048
115
116 /* lower bits of envelope counter */
117 #define ENV_BITS 16
118
119 /* envelope output entries */
120 #define EG_ENT 4096
121 #define EG_STEP (96.0/EG_ENT) /* OPL == 0.1875 dB */
122
123 #if FM_LFO_SUPPORT
124 /* LFO table entries */
125 #define LFO_ENT 512
126 #define LFO_SHIFT (32-9)
127 #define LFO_RATE 0x10000
128 #endif
129
130 /* -------------------- preliminary define section --------------------- */
131 /* attack/decay rate time rate */
132 #define OPM_ARRATE 399128
133 #define OPM_DRRATE 5514396
134 /* It is not checked , because I haven't YM2203 rate */
135 #define OPN_ARRATE OPM_ARRATE
136 #define OPN_DRRATE OPM_DRRATE
137
138 /* PG output cut off level : 78dB(14bit)? */
139 #define PG_CUT_OFF ((int)(78.0/EG_STEP))
140 /* EG output cut off level : 68dB? */
141 #define EG_CUT_OFF ((int)(68.0/EG_STEP))
142
143 #define FREQ_BITS 24 /* frequency turn */
144
145 /* PG counter is 21bits @oct.7 */
146 #define FREQ_RATE (1<<(FREQ_BITS-21))
147 #define TL_BITS (FREQ_BITS+2)
148 /* OPbit = 14(13+sign) : TL_BITS+1(sign) / output = 16bit */
149 #define TL_SHIFT (TL_BITS+1-(14-16))
150
151 /* output final shift */
152 #define FM_OUTSB (TL_SHIFT-FM_OUTPUT_BIT)
153 #define FM_MAXOUT ((1<<(TL_SHIFT-1))-1)
154 #define FM_MINOUT (-(1<<(TL_SHIFT-1)))
155
156 /* -------------------- local defines , macros --------------------- */
157
158 /* envelope counter position */
159 #define EG_AST 0 /* start of Attack phase */
160 #define EG_AED (EG_ENT<<ENV_BITS) /* end of Attack phase */
161 #define EG_DST EG_AED /* start of Decay/Sustain/Release phase */
162 #define EG_DED (EG_DST+(EG_ENT<<ENV_BITS)-1) /* end of Decay/Sustain/Release phase */
163 #define EG_OFF EG_DED /* off */
164 #if FM_SEG_SUPPORT
165 #define EG_UST ((2*EG_ENT)<<ENV_BITS) /* start of SEG UPSISE */
166 #define EG_UED ((3*EG_ENT)<<ENV_BITS) /* end of SEG UPSISE */
167 #endif
168
169 /* register number to channel number , slot offset */
170 #define OPN_CHAN(N) (N&3)
171 #define OPN_SLOT(N) ((N>>2)&3)
172 #define OPM_CHAN(N) (N&7)
173 #define OPM_SLOT(N) ((N>>3)&3)
174 /* slot number */
175 #define SLOT1 0
176 #define SLOT2 2
177 #define SLOT3 1
178 #define SLOT4 3
179
180 /* bit0 = Right enable , bit1 = Left enable */
181 #define OUTD_RIGHT 1
182 #define OUTD_LEFT 2
183 #define OUTD_CENTER 3
184
185 /* FM timer model */
186 #define FM_TIMER_SINGLE (0)
187 #define FM_TIMER_INTERVAL (1)
188
189 /* ---------- OPN / OPM one channel ---------- */
190 typedef struct fm_slot {
191 INT32 *DT; /* detune :DT_TABLE[DT] */
192 int DT2; /* multiple,Detune2:(DT2<<4)|ML for OPM*/
193 int TL; /* total level :TL << 8 */
194 UINT8 KSR; /* key scale rate :3-KSR */
195 const INT32 *AR; /* attack rate :&AR_TABLE[AR<<1] */
196 const INT32 *DR; /* decay rate :&DR_TABLE[DR<<1] */
197 const INT32 *SR; /* sustin rate :&DR_TABLE[SR<<1] */
198 int SL; /* sustin level :SL_TABLE[SL] */
199 const INT32 *RR; /* release rate :&DR_TABLE[RR<<2+2] */
200 UINT8 SEG; /* SSG EG type :SSGEG */
201 UINT8 ksr; /* key scale rate :kcode>>(3-KSR) */
202 UINT32 mul; /* multiple :ML_TABLE[ML] */
203 /* Phase Generator */
204 UINT32 Cnt; /* frequency count : */
205 UINT32 Incr; /* frequency step : */
206 /* Envelope Generator */
207 void (*eg_next)(struct fm_slot *SLOT); /* pointer of phase handler */
208 INT32 evc; /* envelope counter */
209 INT32 eve; /* envelope counter end point */
210 INT32 evs; /* envelope counter step */
211 INT32 evsa; /* envelope step for Attack */
212 INT32 evsd; /* envelope step for Decay */
213 INT32 evss; /* envelope step for Sustain */
214 INT32 evsr; /* envelope step for Release */
215 INT32 TLL; /* adjusted TotalLevel */
216 /* LFO */
217 UINT8 amon; /* AMS enable flag */
218 UINT32 ams; /* AMS depth level of this SLOT */
219 }FM_SLOT;
220
221 typedef struct fm_chan {
222 FM_SLOT SLOT[4];
223 UINT8 PAN; /* PAN :NONE,LEFT,RIGHT or CENTER */
224 UINT8 ALGO; /* Algorythm */
225 UINT8 FB; /* shift count of self feed back */
226 INT32 op1_out[2]; /* op1 output for beedback */
227 /* Algorythm (connection) */
228 INT32 *connect1; /* pointer of SLOT1 output */
229 INT32 *connect2; /* pointer of SLOT2 output */
230 INT32 *connect3; /* pointer of SLOT3 output */
231 INT32 *connect4; /* pointer of SLOT4 output */
232 /* LFO */
233 INT32 pms; /* PMS depth level of channel */
234 UINT32 ams; /* AMS depth level of channel */
235 /* Phase Generator */
236 UINT32 fc; /* fnum,blk :adjusted to sampling rate */
237 UINT8 fn_h; /* freq latch : */
238 UINT8 kcode; /* key code : */
239 } FM_CH;
240
241 /* OPN/OPM common state */
242 typedef struct fm_state {
243 UINT8 index; /* chip index (number of chip) */
244 int clock; /* master clock (Hz) */
245 int rate; /* sampling rate (Hz) */
246 float freqbase; /* frequency base */
247 timer_tm TimerBase; /* Timer base time */
248 UINT8 address; /* address register */
249 UINT8 irq; /* interrupt level */
250 UINT8 irqmask; /* irq mask */
251 UINT8 status; /* status flag */
252 UINT32 mode; /* mode CSM / 3SLOT */
253 int TA; /* timer a */
254 int TAC; /* timer a counter */
255 UINT8 TB; /* timer b */
256 int TBC; /* timer b counter */
257 /* speedup customize */
258 /* local time tables */
259 INT32 DT_TABLE[8][32]; /* DeTune tables */
260 INT32 AR_TABLE[94]; /* Atttack rate tables */
261 INT32 DR_TABLE[94]; /* Decay rate tables */
262 /* Extention Timer and IRQ handler */
263 FM_TIMERHANDLER Timer_Handler;
264 FM_IRQHANDLER IRQ_Handler;
265 /* timer model single / interval */
266 UINT8 timermodel;
267 }FM_ST;
268
269 /* -------------------- tables --------------------- */
270
271 /* sustain lebel table (3db per step) */
272 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
273 #define SC(db) (int)((db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST)
274 static const int SL_TABLE[16]={
275 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
276 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
277 };
278 #undef SC
279
280 /* size of TL_TABLE = sinwave(max cut_off) + cut_off(tl + ksr + envelope + ams) */
281 #define TL_MAX (PG_CUT_OFF+EG_CUT_OFF+1)
282
283 /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
284 /* TL_TABLE[ 0 to TL_MAX ] : plus section */
285 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
286 static INT32 *TL_TABLE = 0;
287
288 /* pointers to TL_TABLE with sinwave output offset */
289 static INT32 *SIN_TABLE[SIN_ENT];
290
291 /* envelope output curve table */
292 #if FM_SEG_SUPPORT
293 /* attack + decay + SSG upside + OFF */
294 static INT32 ENV_CURVE[3*EG_ENT+1];
295 #else
296 /* attack + decay + OFF */
297 static INT32 ENV_CURVE[2*EG_ENT+1];
298 #endif
299 /* envelope counter conversion table when change Decay to Attack phase */
300 static int DRAR_TABLE[EG_ENT];
301
302 #define OPM_DTTABLE OPN_DTTABLE
303 static UINT8 OPN_DTTABLE[4 * 32]={
304 /* this table is YM2151 and YM2612 data */
305 /* FD=0 */
306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 /* FD=1 */
309 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
310 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
311 /* FD=2 */
312 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
313 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
314 /* FD=3 */
315 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
316 8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
317 };
318
319 /* multiple table */
320 #define ML(n) (int)(n*2)
321 static const int MUL_TABLE[4*16]= {
322 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
323 ML(0.50),ML( 1.00),ML( 2.00),ML( 3.00),ML( 4.00),ML( 5.00),ML( 6.00),ML( 7.00),
324 ML(8.00),ML( 9.00),ML(10.00),ML(11.00),ML(12.00),ML(13.00),ML(14.00),ML(15.00),
325 /* DT2=1 *SQL(2) */
326 ML(0.71),ML( 1.41),ML( 2.82),ML( 4.24),ML( 5.65),ML( 7.07),ML( 8.46),ML( 9.89),
327 ML(11.30),ML(12.72),ML(14.10),ML(15.55),ML(16.96),ML(18.37),ML(19.78),ML(21.20),
328 /* DT2=2 *SQL(2.5) */
329 ML( 0.78),ML( 1.57),ML( 3.14),ML( 4.71),ML( 6.28),ML( 7.85),ML( 9.42),ML(10.99),
330 ML(12.56),ML(14.13),ML(15.70),ML(17.27),ML(18.84),ML(20.41),ML(21.98),ML(23.55),
331 /* DT2=3 *SQL(3) */
332 ML( 0.87),ML( 1.73),ML( 3.46),ML( 5.19),ML( 6.92),ML( 8.65),ML(10.38),ML(12.11),
333 ML(13.84),ML(15.57),ML(17.30),ML(19.03),ML(20.76),ML(22.49),ML(24.22),ML(25.95)
334 };
335 #undef ML
336
337 #if FM_LFO_SUPPORT
338
339 #define PMS_RATE 0x400
340 /* LFO runtime work */
341 /*static*/ UINT32 lfo_amd;
342 /*static*/ INT32 lfo_pmd;
343 #endif
344
345 /* Dummy table of Attack / Decay rate ( use when rate == 0 ) */
346 static const INT32 RATE_0[32]=
347 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
348
349 /* -------------------- state --------------------- */
350
351 /* some globals */
352 #define TYPE_SSG 0x01 /* SSG support */
353 #define TYPE_OPN 0x02 /* OPN device */
354 #define TYPE_LFOPAN 0x04 /* OPN type LFO and PAN */
355 #define TYPE_6CH 0x08 /* FM 6CH / 3CH */
356 #define TYPE_DAC 0x10 /* YM2612's DAC device */
357 #define TYPE_ADPCM 0x20 /* two ADPCM unit */
358
359 #define TYPE_YM2203 (TYPE_SSG)
360 #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
361 #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
362 #define TYPE_YM2612 (TYPE_6CH |TYPE_LFOPAN |TYPE_DAC)
363
364 /* current chip state */
365 static void *cur_chip = 0; /* pointer of current chip struct */
366 static FM_ST *State; /* basic status */
367 static FM_CH *cch[8]; /* pointer of FM channels */
368 #if (BUILD_LFO)
369 #if FM_LFO_SUPPORT
370 static UINT32 LFOCnt,LFOIncr; /* LFO PhaseGenerator */
371 #endif
372 #endif
373
374 /* runtime work */
375 /*static*/ INT32 out_ch[4]; /* channel output NONE,LEFT,RIGHT or CENTER */
376 /*static*/ INT32 pg_in1,pg_in2,pg_in3,pg_in4; /* PG input of SLOTs */
377
378 /* -------------------- log output -------------------- */
379 /* log output level */
380 #define LOG_ERR 3 /* ERROR */
381 #define LOG_WAR 2 /* WARNING */
382 #define LOG_INF 1 /* INFORMATION */
383 #define LOG_LEVEL LOG_INF
384
385 //#ifndef __RAINE__
386 //#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
387 //#endif
388 #define LOG(n,x)
389
390 /* ----- limitter ----- */
391 #define Limit(val, max,min) { \
392 if ( val > max ) val = max; \
393 else if ( val < min ) val = min; \
394 }
395
396 #ifndef mix_sample
397 /* ----- buffering one of data(STEREO chip) ----- */
398 #if FM_STEREO_MIX
399 /* stereo mixing */
400 #define FM_BUFFERING_STEREO \
401 { \
402 /* get left & right output with clipping */ \
403 out_ch[OUTD_LEFT] += out_ch[OUTD_CENTER]; \
404 Limit( out_ch[OUTD_LEFT] , FM_MAXOUT, FM_MINOUT ); \
405 out_ch[OUTD_RIGHT] += out_ch[OUTD_CENTER]; \
406 Limit( out_ch[OUTD_RIGHT], FM_MAXOUT, FM_MINOUT ); \
407 /* buffering */ \
408 *bufL++ = out_ch[OUTD_LEFT] >>FM_OUTSB; \
409 *bufL++ = out_ch[OUTD_RIGHT]>>FM_OUTSB; \
410 }
411 #else
412 /* stereo separate */
413 #define FM_BUFFERING_STEREO \
414 { \
415 /* get left & right output with clipping */ \
416 out_ch[OUTD_LEFT] += out_ch[OUTD_CENTER]; \
417 Limit( out_ch[OUTD_LEFT] , FM_MAXOUT, FM_MINOUT ); \
418 out_ch[OUTD_RIGHT] += out_ch[OUTD_CENTER]; \
419 Limit( out_ch[OUTD_RIGHT], FM_MAXOUT, FM_MINOUT ); \
420 /* buffering */ \
421 *bufL++ = out_ch[OUTD_LEFT] >>FM_OUTSB; \
422 *bufR++ = out_ch[OUTD_RIGHT]>>FM_OUTSB; \
423 }
424 #endif
425 #else
426 #if FM_STEREO_MIX
427 #define FM_BUFFERING_STEREO \
428 { \
429 mix_sample(out_ch[OUTD_LEFT],out_ch[OUTD_CENTER]); \
430 *bufL++=out_ch[OUTD_LEFT] >>FM_OUTSB; \
431 mix_sample(out_ch[OUTD_RIGHT],out_ch[OUTD_CENTER]); \
432 *bufR++=out_ch[OUTD_RIGHT] >>FM_OUTSB; \
433 }
434 #else
435 #define FM_BUFFERING_STEREO \
436 { \
437 mix_sample(out_ch[OUTD_LEFT],out_ch[OUTD_CENTER]); \
438 *bufL++=out_ch[OUTD_LEFT] >>FM_OUTSB; \
439 mix_sample(out_ch[OUTD_RIGHT],out_ch[OUTD_CENTER]); \
440 *bufR++=out_ch[OUTD_RIGHT] >>FM_OUTSB; \
441 }
442 #endif
443 #endif
444
445 #if FM_INTERNAL_TIMER
446 /* ----- internal timer mode , update timer */
447 /* ---------- calcrate timer A ---------- */
448 #define INTERNAL_TIMER_A(ST,CSM_CH) \
449 { \
450 if( ST->TAC && (ST->Timer_Handler==0) ) \
451 if( (ST->TAC -= (int)(ST->freqbase*4096)) <= 0 ) \
452 { \
453 TimerAOver( ST ); \
454 /* CSM mode total level latch and auto key on */ \
455 if( ST->mode & 0x80 ) \
456 CSMKeyControll( CSM_CH ); \
457 } \
458 }
459 /* ---------- calcrate timer B ---------- */
460 #define INTERNAL_TIMER_B(ST,step) \
461 { \
462 if( ST->TBC && (ST->Timer_Handler==0) ) \
463 if( (ST->TBC -= (int)(ST->freqbase*4096*step)) <= 0 ) \
464 TimerBOver( ST ); \
465 }
466 #else /* FM_INTERNAL_TIMER */
467 /* external timer mode */
468 #define INTERNAL_TIMER_A(ST,CSM_CH)
469 #define INTERNAL_TIMER_B(ST,step)
470 #endif /* FM_INTERNAL_TIMER */
471
472 /* --------------------- subroutines --------------------- */
473 /* status set and IRQ handling */
FM_STATUS_SET(FM_ST * ST,int flag)474 static INLINE void FM_STATUS_SET(FM_ST *ST,int flag)
475 {
476 /* set status flag */
477 ST->status |= flag;
478 if ( !(ST->irq) && (ST->status & ST->irqmask) )
479 {
480 ST->irq = 1;
481 /* callback user interrupt handler (IRQ is OFF to ON) */
482 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,1);
483 }
484 }
485
486 /* status reset and IRQ handling */
FM_STATUS_RESET(FM_ST * ST,int flag)487 static INLINE void FM_STATUS_RESET(FM_ST *ST,int flag)
488 {
489 /* reset status flag */
490 ST->status &=~flag;
491 if ( (ST->irq) && !(ST->status & ST->irqmask) )
492 {
493 ST->irq = 0;
494 /* callback user interrupt handler (IRQ is ON to OFF) */
495 if(ST->IRQ_Handler) (ST->IRQ_Handler)(ST->index,0);
496 }
497 }
498
499 /* IRQ mask set */
FM_IRQMASK_SET(FM_ST * ST,int flag)500 static INLINE void FM_IRQMASK_SET(FM_ST *ST,int flag)
501 {
502 ST->irqmask = flag;
503 /* IRQ handling check */
504 FM_STATUS_SET(ST,0);
505 FM_STATUS_RESET(ST,0);
506 }
507
508 /* ---------- event hander of Phase Generator ---------- */
509
510 /* Release end -> stop counter */
FM_EG_Release(FM_SLOT * SLOT)511 static void FM_EG_Release( FM_SLOT *SLOT )
512 {
513 SLOT->evc = EG_OFF;
514 SLOT->eve = EG_OFF+1;
515 SLOT->evs = 0;
516 }
517
518 /* SUSTAIN end -> stop counter */
FM_EG_SR(FM_SLOT * SLOT)519 static void FM_EG_SR( FM_SLOT *SLOT )
520 {
521 SLOT->evs = 0;
522 SLOT->evc = EG_OFF;
523 SLOT->eve = EG_OFF+1;
524 }
525
526 /* Decay end -> Sustain */
FM_EG_DR(FM_SLOT * SLOT)527 static void FM_EG_DR( FM_SLOT *SLOT )
528 {
529 SLOT->eg_next = FM_EG_SR;
530 SLOT->evc = SLOT->SL;
531 SLOT->eve = EG_DED;
532 SLOT->evs = SLOT->evss;
533 }
534
535 /* Attack end -> Decay */
FM_EG_AR(FM_SLOT * SLOT)536 static void FM_EG_AR( FM_SLOT *SLOT )
537 {
538 /* next DR */
539 SLOT->eg_next = FM_EG_DR;
540 SLOT->evc = EG_DST;
541 SLOT->eve = SLOT->SL;
542 SLOT->evs = SLOT->evsd;
543 }
544
545 #if FM_SEG_SUPPORT
546 static void FM_EG_SSG_SR( FM_SLOT *SLOT );
547
548 /* SEG down side end */
FM_EG_SSG_DR(FM_SLOT * SLOT)549 static void FM_EG_SSG_DR( FM_SLOT *SLOT )
550 {
551 if( SLOT->SEG&2){
552 /* reverce */
553 SLOT->eg_next = FM_EG_SSG_SR;
554 SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
555 SLOT->eve = EG_UED;
556 SLOT->evs = SLOT->evss;
557 }else{
558 /* again */
559 SLOT->evc = EG_DST;
560 }
561 /* hold */
562 if( SLOT->SEG&1) SLOT->evs = 0;
563 }
564
565 /* SEG upside side end */
FM_EG_SSG_SR(FM_SLOT * SLOT)566 static void FM_EG_SSG_SR( FM_SLOT *SLOT )
567 {
568 if( SLOT->SEG&2){
569 /* reverce */
570 SLOT->eg_next = FM_EG_SSG_DR;
571 SLOT->evc = EG_DST;
572 SLOT->eve = EG_DED;
573 SLOT->evs = SLOT->evsd;
574 }else{
575 /* again */
576 SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
577 }
578 /* hold check */
579 if( SLOT->SEG&1) SLOT->evs = 0;
580 }
581
582 /* SEG Attack end */
FM_EG_SSG_AR(FM_SLOT * SLOT)583 static void FM_EG_SSG_AR( FM_SLOT *SLOT )
584 {
585 if( SLOT->SEG&4){ /* start direction */
586 /* next SSG-SR (upside start ) */
587 SLOT->eg_next = FM_EG_SSG_SR;
588 SLOT->evc = SLOT->SL + (EG_UST - EG_DST);
589 SLOT->eve = EG_UED;
590 SLOT->evs = SLOT->evss;
591 }else{
592 /* next SSG-DR (downside start ) */
593 SLOT->eg_next = FM_EG_SSG_DR;
594 SLOT->evc = EG_DST;
595 SLOT->eve = EG_DED;
596 SLOT->evs = SLOT->evsd;
597 }
598 }
599 #endif /* FM_SEG_SUPPORT */
600
601 /* ----- key on of SLOT ----- */
602 #define FM_KEY_IS(SLOT) ((SLOT)->eg_next!=FM_EG_Release)
603
FM_KEYON(FM_CH * CH,int s)604 static INLINE void FM_KEYON(FM_CH *CH , int s )
605 {
606 FM_SLOT *SLOT = &CH->SLOT[s];
607 if( !FM_KEY_IS(SLOT) )
608 {
609 /* restart Phage Generator */
610 SLOT->Cnt = 0;
611 /* phase -> Attack */
612 #if FM_SEG_SUPPORT
613 if( SLOT->SEG&8 ) SLOT->eg_next = FM_EG_SSG_AR;
614 else
615 #endif
616 SLOT->eg_next = FM_EG_AR;
617 SLOT->evs = SLOT->evsa;
618 #if 0
619 /* convert decay count to attack count */
620 /* --- This caused the problem by credit sound of paper boy. --- */
621 SLOT->evc = EG_AST + DRAR_TABLE[ENV_CURVE[SLOT->evc>>ENV_BITS]];/* + SLOT->evs;*/
622 #else
623 /* reset attack counter */
624 SLOT->evc = EG_AST;
625 #endif
626 SLOT->eve = EG_AED;
627 }
628 }
629 /* ----- key off of SLOT ----- */
FM_KEYOFF(FM_CH * CH,int s)630 static INLINE void FM_KEYOFF(FM_CH *CH , int s )
631 {
632 FM_SLOT *SLOT = &CH->SLOT[s];
633 if( FM_KEY_IS(SLOT) )
634 {
635 /* if Attack phase then adjust envelope counter */
636 if( SLOT->evc < EG_DST )
637 SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
638 /* phase -> Release */
639 SLOT->eg_next = FM_EG_Release;
640 SLOT->eve = EG_DED;
641 SLOT->evs = SLOT->evsr;
642 }
643 }
644
645 /* setup Algorythm and PAN connection */
setup_connection(FM_CH * CH)646 static void setup_connection( FM_CH *CH )
647 {
648 INT32 *carrier = &out_ch[CH->PAN]; /* NONE,LEFT,RIGHT or CENTER */
649
650 switch( CH->ALGO ){
651 case 0:
652 /* PG---S1---S2---S3---S4---OUT */
653 CH->connect1 = &pg_in2;
654 CH->connect2 = &pg_in3;
655 CH->connect3 = &pg_in4;
656 break;
657 case 1:
658 /* PG---S1-+-S3---S4---OUT */
659 /* PG---S2-+ */
660 CH->connect1 = &pg_in3;
661 CH->connect2 = &pg_in3;
662 CH->connect3 = &pg_in4;
663 break;
664 case 2:
665 /* PG---S1------+-S4---OUT */
666 /* PG---S2---S3-+ */
667 CH->connect1 = &pg_in4;
668 CH->connect2 = &pg_in3;
669 CH->connect3 = &pg_in4;
670 break;
671 case 3:
672 /* PG---S1---S2-+-S4---OUT */
673 /* PG---S3------+ */
674 CH->connect1 = &pg_in2;
675 CH->connect2 = &pg_in4;
676 CH->connect3 = &pg_in4;
677 break;
678 case 4:
679 /* PG---S1---S2-+--OUT */
680 /* PG---S3---S4-+ */
681 CH->connect1 = &pg_in2;
682 CH->connect2 = carrier;
683 CH->connect3 = &pg_in4;
684 break;
685 case 5:
686 /* +-S2-+ */
687 /* PG---S1-+-S3-+-OUT */
688 /* +-S4-+ */
689 CH->connect1 = 0; /* special case */
690 CH->connect2 = carrier;
691 CH->connect3 = carrier;
692 break;
693 case 6:
694 /* PG---S1---S2-+ */
695 /* PG--------S3-+-OUT */
696 /* PG--------S4-+ */
697 CH->connect1 = &pg_in2;
698 CH->connect2 = carrier;
699 CH->connect3 = carrier;
700 break;
701 case 7:
702 /* PG---S1-+ */
703 /* PG---S2-+-OUT */
704 /* PG---S3-+ */
705 /* PG---S4-+ */
706 CH->connect1 = carrier;
707 CH->connect2 = carrier;
708 CH->connect3 = carrier;
709 }
710 CH->connect4 = carrier;
711 }
712
713 /* set detune & multiple */
set_det_mul(FM_ST * ST,FM_CH * CH,FM_SLOT * SLOT,int v)714 static INLINE void set_det_mul(FM_ST *ST,FM_CH *CH,FM_SLOT *SLOT,int v)
715 {
716 SLOT->mul = MUL_TABLE[v&0x0f];
717 SLOT->DT = ST->DT_TABLE[(v>>4)&7];
718 CH->SLOT[SLOT1].Incr=-1;
719 }
720
721 /* set total level */
set_tl(FM_CH * CH,FM_SLOT * SLOT,int v,int csmflag)722 static INLINE void set_tl(FM_CH *CH,FM_SLOT *SLOT , int v,int csmflag)
723 {
724 v &= 0x7f;
725 v = (v<<7)|v; /* 7bit -> 14bit */
726 SLOT->TL = (v*EG_ENT)>>14;
727 /* if it is not a CSM channel , latch the total level */
728 if( !csmflag )
729 SLOT->TLL = SLOT->TL;
730 }
731
732 /* set attack rate & key scale */
set_ar_ksr(FM_CH * CH,FM_SLOT * SLOT,int v,INT32 * ar_table)733 static INLINE void set_ar_ksr(FM_CH *CH,FM_SLOT *SLOT,int v,INT32 *ar_table)
734 {
735 SLOT->KSR = 3-(v>>6);
736 SLOT->AR = (v&=0x1f) ? &ar_table[v<<1] : RATE_0;
737 SLOT->evsa = SLOT->AR[SLOT->ksr];
738 if( SLOT->eg_next == FM_EG_AR ) SLOT->evs = SLOT->evsa;
739 CH->SLOT[SLOT1].Incr=-1;
740 }
741 /* set decay rate */
set_dr(FM_SLOT * SLOT,int v,INT32 * dr_table)742 static INLINE void set_dr(FM_SLOT *SLOT,int v,INT32 *dr_table)
743 {
744 SLOT->DR = (v&=0x1f) ? &dr_table[v<<1] : RATE_0;
745 SLOT->evsd = SLOT->DR[SLOT->ksr];
746 if( SLOT->eg_next == FM_EG_DR ) SLOT->evs = SLOT->evsd;
747 }
748 /* set sustain rate */
set_sr(FM_SLOT * SLOT,int v,INT32 * dr_table)749 static INLINE void set_sr(FM_SLOT *SLOT,int v,INT32 *dr_table)
750 {
751 SLOT->SR = (v&=0x1f) ? &dr_table[v<<1] : RATE_0;
752 SLOT->evss = SLOT->SR[SLOT->ksr];
753 if( SLOT->eg_next == FM_EG_SR ) SLOT->evs = SLOT->evss;
754 }
755 /* set release rate */
set_sl_rr(FM_SLOT * SLOT,int v,INT32 * dr_table)756 static INLINE void set_sl_rr(FM_SLOT *SLOT,int v,INT32 *dr_table)
757 {
758 SLOT->SL = SL_TABLE[(v>>4)];
759 SLOT->RR = &dr_table[((v&0x0f)<<2)|2];
760 SLOT->evsr = SLOT->RR[SLOT->ksr];
761 if( SLOT->eg_next == FM_EG_Release ) SLOT->evs = SLOT->evsr;
762 }
763
764 /* operator output calcrator */
765 //#define OP_OUT(PG,EG) SIN_TABLE[(PG/(0x1000000/SIN_ENT))&(SIN_ENT-1)][EG]
766 //#define OP_OUTN(PG,EG) NOISE_TABLE[(PG/(0x1000000/SIN_ENT))&(SIN_ENT-1)][EG]
767 #define OP_OUT(PG,EG) SIN_TABLE[(PG>>13)&0x7ff][EG]
768 #define OP_OUTN(PG,EG) NOISE_TABLE[(PG>>13)&0x7ff][EG]
769
770 /* eg calcration */
771 #if FM_LFO_SUPPORT
772 #define FM_CALC_EG(OUT,SLOT) \
773 { \
774 if( (SLOT.evc += SLOT.evs) >= SLOT.eve) \
775 SLOT.eg_next(&(SLOT)); \
776 OUT = SLOT.TLL+ENV_CURVE[SLOT.evc>>ENV_BITS]; \
777 if(SLOT.ams) \
778 OUT += (SLOT.ams*lfo_amd/LFO_RATE); \
779 }
780 #else
781 #define FM_CALC_EG(OUT,SLOT) \
782 { \
783 if( (SLOT.evc += SLOT.evs) >= SLOT.eve) \
784 SLOT.eg_next(&(SLOT)); \
785 OUT = SLOT.TLL+ENV_CURVE[SLOT.evc>>ENV_BITS]; \
786 }
787 #endif
788
789 /* ---------- calcrate one of channel ---------- */
FM_CALC_CH(FM_CH * CH)790 static INLINE void FM_CALC_CH( FM_CH *CH )
791 {
792 UINT32 eg_out1,eg_out2,eg_out3,eg_out4; //envelope output
793
794 /* Phase Generator */
795 #if FM_LFO_SUPPORT
796 INT32 pms = lfo_pmd * CH->pms / LFO_RATE;
797 if(pms)
798 {
799 pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr + (INT32)(pms * CH->SLOT[SLOT1].Incr) / PMS_RATE);
800 pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr + (INT32)(pms * CH->SLOT[SLOT2].Incr) / PMS_RATE);
801 pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr + (INT32)(pms * CH->SLOT[SLOT3].Incr) / PMS_RATE);
802 pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr + (INT32)(pms * CH->SLOT[SLOT4].Incr) / PMS_RATE);
803 }
804 else
805 #endif
806 {
807 pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr);
808 pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr);
809 pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr);
810 pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr);
811 }
812
813 /* Envelope Generator */
814 FM_CALC_EG(eg_out1,CH->SLOT[SLOT1]);
815 FM_CALC_EG(eg_out2,CH->SLOT[SLOT2]);
816 FM_CALC_EG(eg_out3,CH->SLOT[SLOT3]);
817 FM_CALC_EG(eg_out4,CH->SLOT[SLOT4]);
818
819 /* Connection */
820 if( eg_out1 < EG_CUT_OFF ) /* SLOT 1 */
821 {
822 if( CH->FB ){
823 /* with self feed back */
824 pg_in1 += (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
825 CH->op1_out[1] = CH->op1_out[0];
826 }
827 CH->op1_out[0] = OP_OUT(pg_in1,eg_out1);
828 /* output slot1 */
829 if( !CH->connect1 )
830 {
831 /* algorythm 5 */
832 pg_in2 += CH->op1_out[0];
833 pg_in3 += CH->op1_out[0];
834 pg_in4 += CH->op1_out[0];
835 }else{
836 /* other algorythm */
837 *CH->connect1 += CH->op1_out[0];
838 }
839 }
840 if( eg_out2 < EG_CUT_OFF ) /* SLOT 2 */
841 *CH->connect2 += OP_OUT(pg_in2,eg_out2);
842 if( eg_out3 < EG_CUT_OFF ) /* SLOT 3 */
843 *CH->connect3 += OP_OUT(pg_in3,eg_out3);
844 if( eg_out4 < EG_CUT_OFF ) /* SLOT 4 */
845 *CH->connect4 += OP_OUT(pg_in4,eg_out4);
846 }
847 /* ---------- frequency counter for operater update ---------- */
CALC_FCSLOT(FM_SLOT * SLOT,int fc,int kc)848 static INLINE void CALC_FCSLOT(FM_SLOT *SLOT , int fc , int kc )
849 {
850 int ksr;
851
852 /* frequency step counter */
853 /* SLOT->Incr= (fc+SLOT->DT[kc])*SLOT->mul; */
854 SLOT->Incr= fc*SLOT->mul + SLOT->DT[kc];
855 ksr = kc >> SLOT->KSR;
856 if( SLOT->ksr != ksr )
857 {
858 SLOT->ksr = ksr;
859 /* attack , decay rate recalcration */
860 SLOT->evsa = SLOT->AR[ksr];
861 SLOT->evsd = SLOT->DR[ksr];
862 SLOT->evss = SLOT->SR[ksr];
863 SLOT->evsr = SLOT->RR[ksr];
864 }
865 }
866
867 /* ---------- frequency counter ---------- */
OPN_CALC_FCOUNT(FM_CH * CH)868 static INLINE void OPN_CALC_FCOUNT(FM_CH *CH )
869 {
870 if( CH->SLOT[SLOT1].Incr==-1){
871 int fc = CH->fc;
872 int kc = CH->kcode;
873 CALC_FCSLOT(&CH->SLOT[SLOT1] , fc , kc );
874 CALC_FCSLOT(&CH->SLOT[SLOT2] , fc , kc );
875 CALC_FCSLOT(&CH->SLOT[SLOT3] , fc , kc );
876 CALC_FCSLOT(&CH->SLOT[SLOT4] , fc , kc );
877 }
878 }
879
880 /* ----------- initialize time tabls ----------- */
init_timetables(FM_ST * ST,UINT8 * DTTABLE,int ARRATE,int DRRATE)881 static void init_timetables( FM_ST *ST , UINT8 *DTTABLE , int ARRATE , int DRRATE )
882 {
883 int i,d;
884 float rate;
885
886 /* DeTune table */
887 for (d = 0;d <= 3;d++){
888 for (i = 0;i <= 31;i++){
889 rate = (float)DTTABLE[d*32 + i] * ST->freqbase * FREQ_RATE;
890 ST->DT_TABLE[d][i] = (INT32) rate;
891 ST->DT_TABLE[d+4][i] = (INT32)-rate;
892 }
893 }
894 /* make Attack & Decay tables */
895 for (i = 0;i < 4;i++) ST->AR_TABLE[i] = ST->DR_TABLE[i] = 0;
896 for (i = 4;i < 64;i++){
897 rate = ST->freqbase; /* frequency rate */
898 if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
899 rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
900 rate *= (float)(EG_ENT<<ENV_BITS);
901 ST->AR_TABLE[i] = (INT32)(rate / ARRATE);
902 ST->DR_TABLE[i] = (INT32)(rate / DRRATE);
903 }
904 ST->AR_TABLE[62] = EG_AED;
905 ST->AR_TABLE[63] = EG_AED;
906 for (i = 64;i < 94 ;i++){ /* make for overflow area */
907 ST->AR_TABLE[i] = ST->AR_TABLE[63];
908 ST->DR_TABLE[i] = ST->DR_TABLE[63];
909 }
910
911 #if 0
912 for (i = 0;i < 64 ;i++){
913 LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
914 ((float)(EG_ENT<<ENV_BITS) / ST->AR_TABLE[i]) * (1000.0 / ST->rate),
915 ((float)(EG_ENT<<ENV_BITS) / ST->DR_TABLE[i]) * (1000.0 / ST->rate) ));
916 }
917 #endif
918 }
919
920 /* ---------- reset one of channel ---------- */
reset_channel(FM_ST * ST,FM_CH * CH,int chan)921 static void reset_channel( FM_ST *ST , FM_CH *CH , int chan )
922 {
923 int c,s;
924
925 ST->mode = 0; /* normal mode */
926 FM_STATUS_RESET(ST,0xff);
927 ST->TA = 0;
928 ST->TAC = 0;
929 ST->TB = 0;
930 ST->TBC = 0;
931
932 for( c = 0 ; c < chan ; c++ )
933 {
934 CH[c].fc = 0;
935 CH[c].PAN = OUTD_CENTER;
936 for(s = 0 ; s < 4 ; s++ )
937 {
938 CH[c].SLOT[s].SEG = 0;
939 CH[c].SLOT[s].eg_next= FM_EG_Release;
940 CH[c].SLOT[s].evc = EG_OFF;
941 CH[c].SLOT[s].eve = EG_OFF+1;
942 CH[c].SLOT[s].evs = 0;
943 }
944 }
945 }
946
947 /* ---------- generic table initialize ---------- */
FMInitTable(void)948 static int FMInitTable( void )
949 {
950 int s,t;
951 double rate;
952 int i,j;
953 double pom;
954
955 if (TL_TABLE)
956 {
957 return 1; /* Already initialized */
958 }
959
960 /* allocate total level table plus+minus section */
961 TL_TABLE = (INT32 *)malloc(2*TL_MAX*sizeof(int));
962 if( TL_TABLE == 0 ) return 0;
963 /* make total level table */
964 for (t = 0;t < TL_MAX ;t++){
965 if(t >= PG_CUT_OFF)
966 rate = 0; /* under cut off area */
967 else
968 rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20); /* dB -> voltage */
969 TL_TABLE[ t] = (int)rate;
970 TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
971 /* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
972 }
973
974 /* make sinwave table (pointer of total level) */
975 for (s = 1;s <= SIN_ENT/4;s++){
976 pom = sin(2.0*PI*s/SIN_ENT); /* sin */
977 pom = 20*log10(1/pom); /* -> decibel */
978 j = (int)(pom / EG_STEP); /* TL_TABLE steps */
979 /* cut off check */
980 if(j > PG_CUT_OFF)
981 j = PG_CUT_OFF;
982 /* degree 0 - 90 , degree 180 - 90 : plus section */
983 SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
984 /* degree 180 - 270 , degree 360 - 270 : minus section */
985 SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
986 /* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP)); */
987 }
988 /* degree 0 = degree 180 = off */
989 SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[PG_CUT_OFF];
990
991 /* envelope counter -> envelope output table */
992 for (i=0; i<EG_ENT; i++)
993 {
994 /* ATTACK curve */
995 /* !!!!! preliminary !!!!! */
996 pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
997 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
998 ENV_CURVE[i] = (int)pom;
999 /* DECAY ,RELEASE curve */
1000 ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
1001 #if FM_SEG_SUPPORT
1002 /* DECAY UPSIDE (SSG ENV) */
1003 ENV_CURVE[(EG_UST>>ENV_BITS)+i]= EG_ENT-1-i;
1004 #endif
1005 }
1006 /* off */
1007 ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
1008
1009 /* decay to reattack envelope converttable */
1010 j = EG_ENT-1;
1011 for (i=0; i<EG_ENT; i++)
1012 {
1013 while( j && (ENV_CURVE[j] < i) ) j--;
1014 DRAR_TABLE[i] = j<<ENV_BITS;
1015 /* LOG(LOG_INF,("DR %06X = %06X,AR=%06X\n",i,DRAR_TABLE[i],ENV_CURVE[DRAR_TABLE[i]>>ENV_BITS] )); */
1016 }
1017 return 1;
1018 }
1019
1020
FMCloseTable(void)1021 static void FMCloseTable( void )
1022 {
1023 if( TL_TABLE ) free( TL_TABLE );
1024 TL_TABLE = 0;
1025 return;
1026 }
1027
1028 /* OPN/OPM Mode Register Write */
FMSetMode(FM_ST * ST,int n,int v)1029 static INLINE void FMSetMode( FM_ST *ST ,int n,int v )
1030 {
1031 /* b7 = CSM MODE */
1032 /* b6 = 3 slot mode */
1033 /* b5 = reset b */
1034 /* b4 = reset a */
1035 /* b3 = timer enable b */
1036 /* b2 = timer enable a */
1037 /* b1 = load b */
1038 /* b0 = load a */
1039 ST->mode = v;
1040
1041 /* reset Timer b flag */
1042 if( v & 0x20 )
1043 FM_STATUS_RESET(ST,0x02);
1044 /* reset Timer a flag */
1045 if( v & 0x10 )
1046 FM_STATUS_RESET(ST,0x01);
1047 /* load b */
1048 if( v & 0x02 )
1049 {
1050 if( ST->TBC == 0 )
1051 {
1052 ST->TBC = ( 256-ST->TB)<<4;
1053 /* External timer handler */
1054 if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,ST->TBC,ST->TimerBase);
1055 }
1056 }else if (ST->timermodel == FM_TIMER_INTERVAL)
1057 { /* stop interbval timer */
1058 if( ST->TBC != 0 )
1059 {
1060 ST->TBC = 0;
1061 if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,0,ST->TimerBase);
1062 }
1063 }
1064 /* load a */
1065 if( v & 0x01 )
1066 {
1067 if( ST->TAC == 0 )
1068 {
1069 ST->TAC = (1024-ST->TA);
1070 /* External timer handler */
1071 if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,ST->TAC,ST->TimerBase);
1072 }
1073 }else if (ST->timermodel == FM_TIMER_INTERVAL)
1074 { /* stop interbval timer */
1075 if( ST->TAC != 0 )
1076 {
1077 ST->TAC = 0;
1078 if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,0,ST->TimerBase);
1079 }
1080 }
1081 }
1082
1083 /* Timer A Overflow */
TimerAOver(FM_ST * ST)1084 static INLINE void TimerAOver(FM_ST *ST)
1085 {
1086 /* status set if enabled */
1087 if(ST->mode & 0x04) FM_STATUS_SET(ST,0x01);
1088 /* clear or reload the counter */
1089 if (ST->timermodel == FM_TIMER_INTERVAL)
1090 {
1091 ST->TAC = (1024-ST->TA);
1092 if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,0,ST->TAC,ST->TimerBase);
1093 }
1094 else ST->TAC = 0;
1095 }
1096 /* Timer B Overflow */
TimerBOver(FM_ST * ST)1097 static INLINE void TimerBOver(FM_ST *ST)
1098 {
1099 /* status set if enabled */
1100 if(ST->mode & 0x08) FM_STATUS_SET(ST,0x02);
1101 /* clear or reload the counter */
1102 if (ST->timermodel == FM_TIMER_INTERVAL)
1103 {
1104 ST->TBC = ( 256-ST->TB)<<4;
1105 if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,1,ST->TBC,ST->TimerBase);
1106 }
1107 else ST->TBC = 0;
1108 }
1109 /* CSM Key Controll */
CSMKeyControll(FM_CH * CH)1110 static INLINE void CSMKeyControll(FM_CH *CH)
1111 {
1112 /* all key off */
1113 /* FM_KEYOFF(CH,SLOT1); */
1114 /* FM_KEYOFF(CH,SLOT2); */
1115 /* FM_KEYOFF(CH,SLOT3); */
1116 /* FM_KEYOFF(CH,SLOT4); */
1117 /* total level latch */
1118 CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL;
1119 CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL;
1120 CH->SLOT[SLOT3].TLL = CH->SLOT[SLOT3].TL;
1121 CH->SLOT[SLOT4].TLL = CH->SLOT[SLOT4].TL;
1122 /* all key on */
1123 FM_KEYON(CH,SLOT1);
1124 FM_KEYON(CH,SLOT2);
1125 FM_KEYON(CH,SLOT3);
1126 FM_KEYON(CH,SLOT4);
1127 }
1128
1129 #if BUILD_OPN
1130 /***********************************************************/
1131 /* OPN unit */
1132 /***********************************************************/
1133
1134 /* OPN 3slot struct */
1135 typedef struct opn_3slot {
1136 UINT32 fc[3]; /* fnum3,blk3 :calcrated */
1137 UINT8 fn_h[3]; /* freq3 latch */
1138 UINT8 kcode[3]; /* key code : */
1139 }FM_3SLOT;
1140
1141 /* OPN/A/B common state */
1142 typedef struct opn_f {
1143 UINT8 type; /* chip type */
1144 FM_ST ST; /* general state */
1145 FM_3SLOT SL3; /* 3 slot mode state */
1146 FM_CH *P_CH; /* pointer of CH */
1147 UINT32 FN_TABLE[2048]; /* fnumber -> increment counter */
1148 #if FM_LFO_SUPPORT
1149 /* LFO */
1150 UINT32 LFOCnt;
1151 UINT32 LFOIncr;
1152 UINT32 LFO_FREQ[8];/* LFO FREQ table */
1153 #endif
1154 } FM_OPN;
1155
1156 /* OPN key frequency number -> key code follow table */
1157 /* fnum higher 4bit -> keycode lower 2bit */
1158 static const UINT8 OPN_FKTABLE[16]={0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
1159
1160 #if FM_LFO_SUPPORT
1161 /* OPN LFO waveform table */
1162 static INT32 OPN_LFO_wave[LFO_ENT];
1163 #endif
1164
OPNInitTable(void)1165 static int OPNInitTable(void)
1166 {
1167 int i;
1168
1169 #if FM_LFO_SUPPORT
1170 /* LFO wave table */
1171 for(i=0;i<LFO_ENT;i++)
1172 {
1173 OPN_LFO_wave[i]= i<LFO_ENT/2 ? i*LFO_RATE/(LFO_ENT/2) : (LFO_ENT-i)*LFO_RATE/(LFO_ENT/2);
1174 }
1175 #endif
1176 return FMInitTable();
1177 }
1178
1179 /* ---------- priscaler set(and make time tables) ---------- */
OPNSetPris(FM_OPN * OPN,int pris,int TimerPris,int SSGpris)1180 static void OPNSetPris(FM_OPN *OPN , int pris , int TimerPris, int SSGpris)
1181 {
1182 int i;
1183
1184 /* frequency base */
1185 OPN->ST.freqbase = (OPN->ST.rate) ? ((float)OPN->ST.clock / OPN->ST.rate) / pris : 0;
1186 /* Timer base time */
1187 OPN->ST.TimerBase = (float)TIME_ONE_SEC/((float)OPN->ST.clock / (float)TimerPris);
1188 /* SSG part priscaler set */
1189 if( SSGpris ) SSGClk( OPN->ST.index, OPN->ST.clock * 2 / SSGpris );
1190 /* make time tables */
1191 init_timetables( &OPN->ST , OPN_DTTABLE , OPN_ARRATE , OPN_DRRATE );
1192 /* make fnumber -> increment counter table */
1193 for( i=0 ; i < 2048 ; i++ )
1194 {
1195 /* it is freq table for octave 7 */
1196 /* opn freq counter = 20bit */
1197 OPN->FN_TABLE[i] = (UINT32)( (float)i * OPN->ST.freqbase * FREQ_RATE * (1<<7) / 2 );
1198 }
1199 #if FM_LFO_SUPPORT
1200 /* LFO freq. table */
1201 {
1202 /* 3.98Hz,5.56Hz,6.02Hz,6.37Hz,6.88Hz,9.63Hz,48.1Hz,72.2Hz @ 8MHz */
1203 #define FM_LF(Hz) ((float)LFO_ENT*(1<<LFO_SHIFT)*(Hz)/(8000000.0/144))
1204 static const float freq_table[8] = { FM_LF(3.98),FM_LF(5.56),FM_LF(6.02),FM_LF(6.37),FM_LF(6.88),FM_LF(9.63),FM_LF(48.1),FM_LF(72.2) };
1205 #undef FM_LF
1206 for(i=0;i<8;i++)
1207 {
1208 OPN->LFO_FREQ[i] = (UINT32)(freq_table[i] * OPN->ST.freqbase);
1209 }
1210 }
1211 #endif
1212 /* LOG(LOG_INF,("OPN %d set priscaler %d\n",OPN->ST.index,pris));*/
1213 }
1214
1215 /* ---------- write a OPN mode register 0x20-0x2f ---------- */
OPNWriteMode(FM_OPN * OPN,int r,int v)1216 static void OPNWriteMode(FM_OPN *OPN, int r, int v)
1217 {
1218 UINT8 c;
1219 FM_CH *CH;
1220
1221 switch(r){
1222 case 0x21: /* Test */
1223 break;
1224 #if FM_LFO_SUPPORT
1225 case 0x22: /* LFO FREQ (YM2608/YM2612) */
1226 if( OPN->type & TYPE_LFOPAN )
1227 {
1228 OPN->LFOIncr = (v&0x08) ? OPN->LFO_FREQ[v&7] : 0;
1229 cur_chip = NULL;
1230 }
1231 break;
1232 #endif
1233 case 0x24: /* timer A High 8*/
1234 OPN->ST.TA = (OPN->ST.TA & 0x03)|(((int)v)<<2);
1235 break;
1236 case 0x25: /* timer A Low 2*/
1237 OPN->ST.TA = (OPN->ST.TA & 0x3fc)|(v&3);
1238 break;
1239 case 0x26: /* timer B */
1240 OPN->ST.TB = v;
1241 break;
1242 case 0x27: /* mode , timer controll */
1243 FMSetMode( &(OPN->ST),OPN->ST.index,v );
1244 break;
1245 case 0x28: /* key on / off */
1246 c = v&0x03;
1247 if( c == 3 ) break;
1248 if( (v&0x04) && (OPN->type & TYPE_6CH) ) c+=3;
1249 CH = OPN->P_CH;
1250 CH = &CH[c];
1251 /* csm mode */
1252 /* if( c == 2 && (OPN->ST.mode & 0x80) ) break; */
1253 if(v&0x10) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
1254 if(v&0x20) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
1255 if(v&0x40) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
1256 if(v&0x80) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
1257 /* LOG(LOG_INF,("OPN %d:%d : KEY %02X\n",n,c,v&0xf0));*/
1258 break;
1259 }
1260 }
1261
1262 /* ---------- write a OPN register (0x30-0xff) ---------- */
OPNWriteReg(FM_OPN * OPN,int r,int v)1263 static void OPNWriteReg(FM_OPN *OPN, int r, int v)
1264 {
1265 UINT8 c;
1266 FM_CH *CH;
1267 FM_SLOT *SLOT;
1268
1269 /* 0x30 - 0xff */
1270 if( (c = OPN_CHAN(r)) == 3 ) return; /* 0xX3,0xX7,0xXB,0xXF */
1271 if( (r >= 0x100) /* && (OPN->type & TYPE_6CH) */ ) c+=3;
1272 CH = OPN->P_CH;
1273 CH = &CH[c];
1274
1275 SLOT = &(CH->SLOT[OPN_SLOT(r)]);
1276 switch( r & 0xf0 ) {
1277 case 0x30: /* DET , MUL */
1278 set_det_mul(&OPN->ST,CH,SLOT,v);
1279 break;
1280 case 0x40: /* TL */
1281 set_tl(CH,SLOT,v,(c == 2) && (OPN->ST.mode & 0x80) );
1282 break;
1283 case 0x50: /* KS, AR */
1284 set_ar_ksr(CH,SLOT,v,OPN->ST.AR_TABLE);
1285 break;
1286 case 0x60: /* DR */
1287 /* bit7 = AMS_ON ENABLE(YM2612) */
1288 set_dr(SLOT,v,OPN->ST.DR_TABLE);
1289 #if FM_LFO_SUPPORT
1290 if( OPN->type & TYPE_LFOPAN)
1291 {
1292 SLOT->amon = v>>7;
1293 SLOT->ams = CH->ams * SLOT->amon;
1294 }
1295 #endif
1296 break;
1297 case 0x70: /* SR */
1298 set_sr(SLOT,v,OPN->ST.DR_TABLE);
1299 break;
1300 case 0x80: /* SL, RR */
1301 set_sl_rr(SLOT,v,OPN->ST.DR_TABLE);
1302 break;
1303 case 0x90: /* SSG-EG */
1304 #if !FM_SEG_SUPPORT
1305 if(v&0x08) LOG(LOG_ERR,("OPN %d,%d,%d :SSG-TYPE envelope selected (not supported )\n",OPN->ST.index,c,OPN_SLOT(r)));
1306 #endif
1307 SLOT->SEG = v&0x0f;
1308 break;
1309 case 0xa0:
1310 switch( OPN_SLOT(r) ){
1311 case 0: /* 0xa0-0xa2 : FNUM1 */
1312 {
1313 UINT32 fn = (((UINT32)( (CH->fn_h)&7))<<8) + v;
1314 UINT8 blk = CH->fn_h>>3;
1315 /* make keyscale code */
1316 CH->kcode = (blk<<2)|OPN_FKTABLE[(fn>>7)];
1317 /* make basic increment counter 32bit = 1 cycle */
1318 CH->fc = OPN->FN_TABLE[fn]>>(7-blk);
1319 CH->SLOT[SLOT1].Incr=-1;
1320 }
1321 break;
1322 case 1: /* 0xa4-0xa6 : FNUM2,BLK */
1323 CH->fn_h = v&0x3f;
1324 break;
1325 case 2: /* 0xa8-0xaa : 3CH FNUM1 */
1326 if( r < 0x100)
1327 {
1328 UINT32 fn = (((UINT32)(OPN->SL3.fn_h[c]&7))<<8) + v;
1329 UINT8 blk = OPN->SL3.fn_h[c]>>3;
1330 /* make keyscale code */
1331 OPN->SL3.kcode[c]= (blk<<2)|OPN_FKTABLE[(fn>>7)];
1332 /* make basic increment counter 32bit = 1 cycle */
1333 OPN->SL3.fc[c] = OPN->FN_TABLE[fn]>>(7-blk);
1334 (OPN->P_CH)[2].SLOT[SLOT1].Incr=-1;
1335 }
1336 break;
1337 case 3: /* 0xac-0xae : 3CH FNUM2,BLK */
1338 if( r < 0x100)
1339 OPN->SL3.fn_h[c] = v&0x3f;
1340 break;
1341 }
1342 break;
1343 case 0xb0:
1344 switch( OPN_SLOT(r) ){
1345 case 0: /* 0xb0-0xb2 : FB,ALGO */
1346 {
1347 int feedback = (v>>3)&7;
1348 CH->ALGO = v&7;
1349 CH->FB = feedback ? 8+1 - feedback : 0;
1350 setup_connection( CH );
1351 }
1352 break;
1353 case 1: /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2608) */
1354 if( OPN->type & TYPE_LFOPAN)
1355 {
1356 #if FM_LFO_SUPPORT
1357 /* b0-2 PMS */
1358 /* 0,3.4,6.7,10,14,20,40,80(cent) */
1359 static const float pmd_table[8]={0,3.4,6.7,10,14,20,40,80};
1360 static const int amd_table[4]={(int)(0/EG_STEP),(int)(1.4/EG_STEP),(int)(5.9/EG_STEP),(int)(11.8/EG_STEP) };
1361 CH->pms = (INT32)( (1.5/1200.0)*pmd_table[v & 7] * PMS_RATE);
1362 /* b4-5 AMS */
1363 /* 0 , 1.4 , 5.9 , 11.8(dB) */
1364 CH->ams = amd_table[(v>>4) & 0x03];
1365 CH->SLOT[SLOT1].ams = CH->ams * CH->SLOT[SLOT1].amon;
1366 CH->SLOT[SLOT2].ams = CH->ams * CH->SLOT[SLOT2].amon;
1367 CH->SLOT[SLOT3].ams = CH->ams * CH->SLOT[SLOT3].amon;
1368 CH->SLOT[SLOT4].ams = CH->ams * CH->SLOT[SLOT4].amon;
1369 #endif
1370 /* PAN */
1371 CH->PAN = (v>>6)&0x03; /* PAN : b6 = R , b7 = L */
1372 setup_connection( CH );
1373 /* LOG(LOG_INF,("OPN %d,%d : PAN %d\n",n,c,CH->PAN));*/
1374 }
1375 break;
1376 }
1377 break;
1378 }
1379 }
1380 #endif /* BUILD_OPN */
1381
1382 #if BUILD_YM2203
1383 /*******************************************************************************/
1384 /* YM2203 local section */
1385 /*******************************************************************************/
1386
1387 /* here's the virtual YM2203(OPN) */
1388 typedef struct ym2203_f {
1389 FM_OPN OPN; /* OPN state */
1390 FM_CH CH[3]; /* channel state */
1391 } YM2203;
1392
1393 static YM2203 *FM2203=NULL; /* array of YM2203's */
1394 static int YM2203NumChips; /* total chip */
1395
1396 /* ---------- update one of chip ----------- */
YM2203UpdateOne(int num,INT16 * buffer,int length)1397 void YM2203UpdateOne(int num, INT16 *buffer, int length)
1398 {
1399 YM2203 *F2203 = &(FM2203[num]);
1400 FM_OPN *OPN = &(FM2203[num].OPN);
1401 int i;
1402 FM_CH *ch;
1403 FMSAMPLE *buf = buffer;
1404
1405 cur_chip = (void *)F2203;
1406 State = &F2203->OPN.ST;
1407 cch[0] = &F2203->CH[0];
1408 cch[1] = &F2203->CH[1];
1409 cch[2] = &F2203->CH[2];
1410 #if FM_LFO_SUPPORT
1411 /* LFO */
1412 lfo_amd = lfo_pmd = 0;
1413 #endif
1414 /* frequency counter channel A */
1415 OPN_CALC_FCOUNT( cch[0] );
1416 /* frequency counter channel B */
1417 OPN_CALC_FCOUNT( cch[1] );
1418 /* frequency counter channel C */
1419 if( (State->mode & 0xc0) ){
1420 /* 3SLOT MODE */
1421 if( cch[2]->SLOT[SLOT1].Incr==-1){
1422 /* 3 slot mode */
1423 CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
1424 CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
1425 CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
1426 CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
1427 }
1428 }else OPN_CALC_FCOUNT( cch[2] );
1429
1430 for (i=0;i<length;i++)
1431 {
1432 /* channel A channel B channel C */
1433 out_ch[OUTD_CENTER] = 0;
1434 /* calcrate FM */
1435 for( ch=cch[0] ; ch <= cch[2] ; ch++)
1436 FM_CALC_CH( ch );
1437 /* limit check */
1438 Limit( out_ch[OUTD_CENTER] , FM_MAXOUT, FM_MINOUT );
1439 /* store to sound buffer */
1440 buf[i] = out_ch[OUTD_CENTER] >> FM_OUTSB;
1441 /* timer controll */
1442 INTERNAL_TIMER_A( State , cch[2] )
1443 }
1444 INTERNAL_TIMER_B(State,length)
1445 }
1446
1447 /* ---------- reset one of chip ---------- */
YM2203ResetChip(int num)1448 void YM2203ResetChip(int num)
1449 {
1450 int i;
1451 FM_OPN *OPN = &(FM2203[num].OPN);
1452
1453 /* Reset Priscaler */
1454 OPNSetPris( OPN , 6*12 , 6*12 ,4); /* 1/6 , 1/4 */
1455 /* reset SSG section */
1456 SSGReset(OPN->ST.index);
1457 /* status clear */
1458 FM_IRQMASK_SET(&OPN->ST,0x03);
1459 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
1460 reset_channel( &OPN->ST , FM2203[num].CH , 3 );
1461 /* reset OPerator paramater */
1462 for(i = 0xb6 ; i >= 0xb4 ; i-- ) OPNWriteReg(OPN,i,0xc0); /* PAN RESET */
1463 for(i = 0xb2 ; i >= 0x30 ; i-- ) OPNWriteReg(OPN,i,0);
1464 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
1465 }
1466
1467 /* ---------- Initialize YM2203 emulator(s) ---------- */
1468 /* 'num' is the number of virtual YM2203's to allocate */
1469 /* 'rate' is sampling rate and 'bufsiz' is the size of the */
1470 /* buffer that should be updated at each interval */
YM2203Init(int num,int clock,int rate,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)1471 int YM2203Init(int num, int clock, int rate,
1472 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
1473 {
1474 int i;
1475
1476 if (FM2203) return (-1); /* duplicate init. */
1477 cur_chip = NULL; /* hiro-shi!! */
1478
1479 YM2203NumChips = num;
1480
1481 /* allocate ym2203 state space */
1482 if( (FM2203 = (YM2203 *)malloc(sizeof(YM2203) * YM2203NumChips))==NULL)
1483 return (-1);
1484 /* clear */
1485 memset(FM2203,0,sizeof(YM2203) * YM2203NumChips);
1486 /* allocate total level table (128kb space) */
1487 if( !OPNInitTable() )
1488 {
1489 free( FM2203 );
1490 return (-1);
1491 }
1492 for ( i = 0 ; i < YM2203NumChips; i++ ) {
1493 FM2203[i].OPN.ST.index = i;
1494 FM2203[i].OPN.type = TYPE_YM2203;
1495 FM2203[i].OPN.P_CH = FM2203[i].CH;
1496 FM2203[i].OPN.ST.clock = clock;
1497 FM2203[i].OPN.ST.rate = rate;
1498 /* FM2203[i].OPN.ST.irq = 0; */
1499 /* FM2203[i].OPN.ST.satus = 0; */
1500 FM2203[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
1501 /* Extend handler */
1502 FM2203[i].OPN.ST.Timer_Handler = TimerHandler;
1503 FM2203[i].OPN.ST.IRQ_Handler = IRQHandler;
1504 YM2203ResetChip(i);
1505 }
1506 return(0);
1507 }
1508
1509 /* ---------- shut down emurator ----------- */
YM2203Shutdown(void)1510 void YM2203Shutdown(void)
1511 {
1512 if (!FM2203) return;
1513
1514 FMCloseTable();
1515 free(FM2203);
1516 FM2203 = NULL;
1517 }
1518
1519 /* ---------- YM2203 I/O interface ---------- */
YM2203Write(int n,int a,UINT8 v)1520 int YM2203Write(int n,int a,UINT8 v)
1521 {
1522 FM_OPN *OPN = &(FM2203[n].OPN);
1523
1524 if( !(a&1) )
1525 { /* address port */
1526 OPN->ST.address = v & 0xff;
1527 /* Write register to SSG emurator */
1528 if( v < 16 ) SSGWrite(n,0,v);
1529 switch(OPN->ST.address)
1530 {
1531 case 0x2d: /* divider sel */
1532 OPNSetPris( OPN, 6*12, 6*12 ,4); /* OPN 1/6 , SSG 1/4 */
1533 break;
1534 case 0x2e: /* divider sel */
1535 OPNSetPris( OPN, 3*12, 3*12,2); /* OPN 1/3 , SSG 1/2 */
1536 break;
1537 case 0x2f: /* divider sel */
1538 OPNSetPris( OPN, 2*12, 2*12,1); /* OPN 1/2 , SSG 1/1 */
1539 break;
1540 }
1541 }
1542 else
1543 { /* data port */
1544 int addr = OPN->ST.address;
1545 switch( addr & 0xf0 )
1546 {
1547 case 0x00: /* 0x00-0x0f : SSG section */
1548 /* Write data to SSG emurator */
1549 SSGWrite(n,a,v);
1550 break;
1551 case 0x20: /* 0x20-0x2f : Mode section */
1552 YM2203UpdateReq(n);
1553 /* write register */
1554 OPNWriteMode(OPN,addr,v);
1555 break;
1556 default: /* 0x30-0xff : OPN section */
1557 YM2203UpdateReq(n);
1558 /* write register */
1559 OPNWriteReg(OPN,addr,v);
1560 }
1561 }
1562 return OPN->ST.irq;
1563 }
1564
YM2203Read(int n,int a)1565 UINT8 YM2203Read(int n,int a)
1566 {
1567 YM2203 *F2203 = &(FM2203[n]);
1568 int addr = F2203->OPN.ST.address;
1569 int ret = 0;
1570
1571 if( !(a&1) )
1572 { /* status port */
1573 ret = F2203->OPN.ST.status;
1574 }
1575 else
1576 { /* data port (ONLY SSG) */
1577 if( addr < 16 ) ret = SSGRead(n);
1578 }
1579 return ret;
1580 }
1581
YM2203TimerOver(int n,int c)1582 int YM2203TimerOver(int n,int c)
1583 {
1584 YM2203 *F2203 = &(FM2203[n]);
1585
1586 if( c )
1587 { /* Timer B */
1588 TimerBOver( &(F2203->OPN.ST) );
1589 }
1590 else
1591 { /* Timer A */
1592 YM2203UpdateReq(n);
1593 /* timer update */
1594 TimerAOver( &(F2203->OPN.ST) );
1595 /* CSM mode key,TL controll */
1596 if( F2203->OPN.ST.mode & 0x80 )
1597 { /* CSM mode total level latch and auto key on */
1598 CSMKeyControll( &(F2203->CH[2]) );
1599 }
1600 }
1601 return F2203->OPN.ST.irq;
1602 }
1603
1604 #endif /* BUILD_YM2203 */
1605
1606 #if (BUILD_YM2608||BUILD_OPNB)
1607 /* adpcm type A struct */
1608 typedef struct adpcm_state {
1609 UINT8 flag; /* port state */
1610 UINT8 flagMask; /* arrived flag mask */
1611 UINT8 now_data;
1612 UINT32 now_addr;
1613 UINT32 now_step;
1614 UINT32 step;
1615 UINT32 start;
1616 UINT32 end;
1617 int IL;
1618 int volume; /* calcrated mixing level */
1619 INT32 *pan; /* &out_ch[OPN_xxxx] */
1620 int /*adpcmm,*/ adpcmx, adpcmd;
1621 int adpcml; /* hiro-shi!! */
1622 }ADPCM_CH;
1623
1624 /* here's the virtual YM2610 */
1625 typedef struct ym2610_f {
1626 FM_OPN OPN; /* OPN state */
1627 FM_CH CH[6]; /* channel state */
1628 int address1; /* address register1 */
1629 /* ADPCM-A unit */
1630 UINT8 *pcmbuf; /* pcm rom buffer */
1631 UINT32 pcm_size; /* size of pcm rom */
1632 INT32 *adpcmTL; /* adpcmA total level */
1633 ADPCM_CH adpcm[6]; /* adpcm channels */
1634 UINT32 adpcmreg[0x30]; /* registers */
1635 UINT8 adpcm_arrivedEndAddress;
1636 /* Delta-T ADPCM unit */
1637 YM_DELTAT deltaT;
1638 } YM2610;
1639
1640 /* here's the virtual YM2608 */
1641 typedef YM2610 YM2608;
1642 #endif /* (BUILD_YM2608||BUILD_OPNB) */
1643
1644 #if BUILD_FM_ADPCMA
1645 /***************************************************************/
1646 /* ADPCMA units are made by Hiromitsu Shioya (MMSND) */
1647 /***************************************************************/
1648
1649 /**** YM2610 ADPCM defines ****/
1650 #define ADPCMA_MIXING_LEVEL (3) /* ADPCMA mixing level */
1651 #define ADPCM_SHIFT (16) /* frequency step rate */
1652 #define ADPCMA_ADDRESS_SHIFT 8 /* adpcm A address shift */
1653
1654 //#define ADPCMA_DECODE_RANGE 1024
1655 #define ADPCMA_DECODE_RANGE 2048
1656 #define ADPCMA_DECODE_MIN (-(ADPCMA_DECODE_RANGE*ADPCMA_MIXING_LEVEL))
1657 #define ADPCMA_DECODE_MAX ((ADPCMA_DECODE_RANGE*ADPCMA_MIXING_LEVEL)-1)
1658 #define ADPCMA_VOLUME_DIV 1
1659
1660 static UINT8 *pcmbufA;
1661 static UINT32 pcmsizeA;
1662
1663 /************************************************************/
1664 /************************************************************/
1665 /* --------------------- subroutines --------------------- */
1666 /************************************************************/
1667 /************************************************************/
1668 /************************/
1669 /* ADPCM A tables */
1670 /************************/
1671 static int jedi_table[(48+1)*16];
1672 static int decode_tableA1[16] = {
1673 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
1674 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
1675 };
1676
1677 /* 0.9 , 0.9 , 0.9 , 0.9 , 1.2 , 1.6 , 2.0 , 2.4 */
1678 /* 8 = -1 , 2 5 8 11 */
1679 /* 9 = -1 , 2 5 9 13 */
1680 /* 10= -1 , 2 6 10 14 */
1681 /* 12= -1 , 2 7 12 17 */
1682 /* 20= -2 , 4 12 20 32 */
1683
1684 #if 1
InitOPNB_ADPCMATable(void)1685 static void InitOPNB_ADPCMATable(void){
1686 int step, nib;
1687
1688 for (step = 0; step <= 48; step++)
1689 {
1690 float stepval = floor(16.0 * pow (11.0 / 10.0, (double)step) * ADPCMA_MIXING_LEVEL);
1691 /* loop over all nibbles and compute the difference */
1692 for (nib = 0; nib < 16; nib++)
1693 {
1694 int value = (int)stepval*((nib&0x07)*2+1)/8;
1695 jedi_table[step*16+nib] = (nib&0x08) ? -value : value;
1696 }
1697 }
1698 }
1699 #else
1700 static int decode_tableA2[49] = {
1701 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001c, 0x001f,
1702 0x0022, 0x0025, 0x0029, 0x002d, 0x0032, 0x0037, 0x003c, 0x0042,
1703 0x0049, 0x0050, 0x0058, 0x0061, 0x006b, 0x0076, 0x0082, 0x008f,
1704 0x009d, 0x00ad, 0x00be, 0x00d1, 0x00e6, 0x00fd, 0x0117, 0x0133,
1705 0x0151, 0x0173, 0x0198, 0x01c1, 0x01ee, 0x0220, 0x0256, 0x0292,
1706 0x02d4, 0x031c, 0x036c, 0x03c3, 0x0424, 0x048e, 0x0502, 0x0583,
1707 0x0610
1708 };
InitOPNB_ADPCMATable(void)1709 static void InitOPNB_ADPCMATable(void){
1710 int ta,tb,tc;
1711 for(ta=0;ta<49;ta++){
1712 for(tb=0;tb<16;tb++){
1713 tc=0;
1714 if(tb&0x04){tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL));}
1715 if(tb&0x02){tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL)>>1);}
1716 if(tb&0x01){tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL)>>2);}
1717 tc+=((decode_tableA2[ta]*ADPCMA_MIXING_LEVEL)>>3);
1718 if(tb&0x08){tc=(0-tc);}
1719 jedi_table[ta*16+tb]=tc;
1720 }
1721 }
1722 }
1723 #endif
1724
1725 /**** ADPCM A (Non control type) ****/
OPNB_ADPCM_CALC_CHA(YM2610 * F2610,ADPCM_CH * ch)1726 static INLINE void OPNB_ADPCM_CALC_CHA( YM2610 *F2610, ADPCM_CH *ch )
1727 {
1728 UINT32 step;
1729 int data;
1730
1731 ch->now_step += ch->step;
1732 if ( ch->now_step >= (1<<ADPCM_SHIFT) )
1733 {
1734 step = ch->now_step >> ADPCM_SHIFT;
1735 ch->now_step &= (1<<ADPCM_SHIFT)-1;
1736 /* end check */
1737 if ( (ch->now_addr+step) > (ch->end<<1) ) {
1738 ch->flag = 0;
1739 F2610->adpcm_arrivedEndAddress |= ch->flagMask;
1740 return;
1741 }
1742 do{
1743 #if 0
1744 if ( ch->now_addr > (pcmsizeA<<1) ) {
1745 LOG(LOG_WAR,("YM2610: Attempting to play past adpcm rom size!\n" ));
1746 return;
1747 }
1748 #endif
1749 if( ch->now_addr&1 ) data = ch->now_data & 0x0f;
1750 else
1751 {
1752 ch->now_data = *(pcmbufA+(ch->now_addr>>1));
1753 data = (ch->now_data >> 4)&0x0f;
1754 }
1755 ch->now_addr++;
1756
1757 ch->adpcmx += jedi_table[ch->adpcmd+data];
1758 Limit( ch->adpcmx,ADPCMA_DECODE_MAX, ADPCMA_DECODE_MIN );
1759 ch->adpcmd += decode_tableA1[data];
1760 Limit( ch->adpcmd, 48*16, 0*16 );
1761 /**** calc pcm * volume data ****/
1762 ch->adpcml = ch->adpcmx * ch->volume;
1763 }while(--step);
1764 }
1765 /* output for work of output channels (out_ch[OPNxxxx])*/
1766 *(ch->pan) += ch->adpcml;
1767 }
1768
1769 /* ADPCM type A */
FM_ADPCMAWrite(YM2610 * F2610,int r,int v)1770 static void FM_ADPCMAWrite(YM2610 *F2610,int r,int v)
1771 {
1772 ADPCM_CH *adpcm = F2610->adpcm;
1773 UINT8 c = r&0x07;
1774
1775 F2610->adpcmreg[r] = v&0xff; /* stock data */
1776 switch( r ){
1777 case 0x00: /* DM,--,C5,C4,C3,C2,C1,C0 */
1778 /* F2610->port1state = v&0xff; */
1779 if( !(v&0x80) ){
1780 /* KEY ON */
1781 for( c = 0; c < 6; c++ ){
1782 if( (1<<c)&v ){
1783 /**** start adpcm ****/
1784 adpcm[c].step = (UINT32)((float)(1<<ADPCM_SHIFT)*((float)F2610->OPN.ST.freqbase)/3.0);
1785 adpcm[c].now_addr = adpcm[c].start<<1;
1786 adpcm[c].now_step = (1<<ADPCM_SHIFT)-adpcm[c].step;
1787 /*adpcm[c].adpcmm = 0;*/
1788 adpcm[c].adpcmx = 0;
1789 adpcm[c].adpcmd = 0;
1790 adpcm[c].adpcml = 0;
1791 adpcm[c].flag = 1;
1792 if(F2610->pcmbuf==NULL){ // Check ROM Mapped
1793 LOG(LOG_WAR,("YM2610: ADPCM-A rom not mapped\n"));
1794 adpcm[c].flag = 0;
1795 } else{
1796 if(adpcm[c].end >= F2610->pcm_size){ // Check End in Range
1797 LOG(LOG_WAR,("YM2610: ADPCM-A end out of range: $%08x\n",adpcm[c].end));
1798 adpcm[c].end = F2610->pcm_size-1;
1799 }
1800 if(adpcm[c].start >= F2610->pcm_size)
1801 { // Check Start in Range
1802 LOG(LOG_WAR,("YM2610: ADPCM-A start out of range: $%08x\n",adpcm[c].start));
1803 adpcm[c].flag = 0;
1804 }
1805 /*LOG(LOG_WAR,("YM2610: Start %06X : %02X %02X %02X\n",adpcm[c].start,
1806 pcmbufA[adpcm[c].start],pcmbufA[adpcm[c].start+1],pcmbufA[adpcm[c].start+2]));*/
1807 }
1808 } /*** (1<<c)&v ***/
1809 } /**** for loop ****/
1810 } else{
1811 /* KEY OFF */
1812 for( c = 0; c < 6; c++ ){
1813 if( (1<<c)&v ) adpcm[c].flag = 0;
1814 }
1815 }
1816 break;
1817 case 0x01: /* B0-5 = TL 0.75dB step */
1818 F2610->adpcmTL = &(TL_TABLE[((v&0x3f)^0x3f)*(int)(0.75/EG_STEP)]);
1819 for( c = 0; c < 6; c++ )
1820 {
1821 adpcm[c].volume = F2610->adpcmTL[adpcm[c].IL*(int)(0.75/EG_STEP)] / ADPCMA_DECODE_RANGE / ADPCMA_VOLUME_DIV;
1822 /**** calc pcm * volume data ****/
1823 adpcm[c].adpcml = adpcm[c].adpcmx * adpcm[c].volume;
1824 }
1825 break;
1826 default:
1827 c = r&0x07;
1828 if( c >= 0x06 ) return;
1829 switch( r&0x38 ){
1830 case 0x08: /* B7=L,B6=R,B4-0=IL */
1831 adpcm[c].IL = (v&0x1f)^0x1f;
1832 adpcm[c].volume = F2610->adpcmTL[adpcm[c].IL*(int)(0.75/EG_STEP)] / ADPCMA_DECODE_RANGE / ADPCMA_VOLUME_DIV;
1833 adpcm[c].pan = &out_ch[(v>>6)&0x03];
1834 /**** calc pcm * volume data ****/
1835 adpcm[c].adpcml = adpcm[c].adpcmx * adpcm[c].volume;
1836 break;
1837 case 0x10:
1838 case 0x18:
1839 adpcm[c].start = ( (F2610->adpcmreg[0x18 + c]*0x0100 | F2610->adpcmreg[0x10 + c]) << ADPCMA_ADDRESS_SHIFT);
1840 break;
1841 case 0x20:
1842 case 0x28:
1843 adpcm[c].end = ( (F2610->adpcmreg[0x28 + c]*0x0100 | F2610->adpcmreg[0x20 + c]) << ADPCMA_ADDRESS_SHIFT);
1844 adpcm[c].end += (1<<ADPCMA_ADDRESS_SHIFT) - 1;
1845 break;
1846 }
1847 }
1848 }
1849
1850 #endif /* BUILD_FM_ADPCMA */
1851
1852 #if BUILD_YM2608
1853 /*******************************************************************************/
1854 /* YM2608 local section */
1855 /*******************************************************************************/
1856 static YM2608 *FM2608=NULL; /* array of YM2608's */
1857 static int YM2608NumChips; /* total chip */
1858
1859 /* YM2608 Rhythm Number */
1860 #define RY_BD 0
1861 #define RY_SD 1
1862 #define RY_TOP 2
1863 #define RY_HH 3
1864 #define RY_TOM 4
1865 #define RY_RIM 5
1866
1867 #if 0
1868 /* Get next pcm data */
1869 static INLINE int YM2608ReadADPCM(int n)
1870 {
1871 YM2608 *F2608 = &(FM2608[n]);
1872 if( F2608->ADMode & 0x20 )
1873 { /* buffer memory */
1874 /* F2203->OPN.ST.status |= 0x04; */
1875 return 0;
1876 }
1877 else
1878 { /* from PCM data register */
1879 FM_STATUS_SET(F2608->OPN.ST,0x08); /* BRDY = 1 */
1880 return F2608->ADData;
1881 }
1882 }
1883
1884 /* Put decoded data */
1885 static INLINE void YM2608WriteADPCM(int n,int v)
1886 {
1887 YM2608 *F2608 = &(FM2608[n]);
1888 if( F2608->ADMode & 0x20 )
1889 { /* for buffer */
1890 return;
1891 }
1892 else
1893 { /* for PCM data port */
1894 F2608->ADData = v;
1895 FM_STATUS_SET(F2608->OPN.ST,0x08) /* BRDY = 1 */
1896 }
1897 }
1898 #endif
1899
1900 /* ---------- IRQ flag Controll Write 0x110 ---------- */
YM2608IRQFlagWrite(FM_ST * ST,int n,int v)1901 static INLINE void YM2608IRQFlagWrite(FM_ST *ST,int n,int v)
1902 {
1903 if( v & 0x80 )
1904 { /* Reset IRQ flag */
1905 FM_STATUS_RESET(ST,0xff);
1906 }
1907 else
1908 { /* Set IRQ mask */
1909 /* !!!!!!!!!! pending !!!!!!!!!! */
1910 }
1911 }
1912
1913 #ifdef YM2608_RHYTHM_PCM
1914 /**** RYTHM (PCM) ****/
YM2608_RYTHM(YM2608 * F2608,ADPCM_CH * ch)1915 static INLINE void YM2608_RYTHM( YM2608 *F2608, ADPCM_CH *ch )
1916
1917 {
1918 UINT32 step;
1919
1920 ch->now_step += ch->step;
1921 if ( ch->now_step >= (1<<ADPCM_SHIFT) )
1922 {
1923 step = ch->now_step >> ADPCM_SHIFT;
1924 ch->now_step &= (1<<ADPCM_SHIFT)-1;
1925 /* end check */
1926 if ( (ch->now_addr+step) > (ch->end<<1) ) {
1927 ch->flag = 0;
1928 F2608->adpcm_arrivedEndAddress |= ch->flagMask;
1929 return;
1930 }
1931 do{
1932 /* get a next pcm data */
1933 ch->adpcmx = ((short *)pcmbufA)[ch->now_addr];
1934 ch->now_addr++;
1935 /**** calc pcm * volume data ****/
1936 ch->adpcml = ch->adpcmx * ch->volume;
1937 }while(--step);
1938 }
1939 /* output for work of output channels (out_ch[OPNxxxx])*/
1940 *(ch->pan) += ch->adpcml;
1941 }
1942 #endif /* YM2608_RHYTHM_PCM */
1943
1944 /* ---------- update one of chip ----------- */
YM2608UpdateOne(int num,INT16 ** buffer,int length)1945 void YM2608UpdateOne(int num, INT16 **buffer, int length)
1946 {
1947 YM2608 *F2608 = &(FM2608[num]);
1948 FM_OPN *OPN = &(FM2608[num].OPN);
1949 YM_DELTAT *DELTAT = &(F2608[num].deltaT);
1950 int j;
1951 FM_CH *ch;
1952 FMSAMPLE *bufL,*bufR;
1953
1954 /* setup DELTA-T unit */
1955 YM_DELTAT_DECODE_PRESET(DELTAT);
1956 DELTAT->arrivedFlag = 0; /* ASG */
1957 DELTAT->flagMask = 1; /* ASG */
1958
1959 /* set bufer */
1960 bufL = buffer[0];
1961 bufR = buffer[1];
1962
1963 if( (void *)F2608 != cur_chip ){
1964 cur_chip = (void *)F2608;
1965
1966 State = &OPN->ST;
1967 cch[0] = &F2608->CH[0];
1968 cch[1] = &F2608->CH[1];
1969 cch[2] = &F2608->CH[2];
1970 cch[3] = &F2608->CH[3];
1971 cch[4] = &F2608->CH[4];
1972 cch[5] = &F2608->CH[5];
1973 /* setup adpcm rom address */
1974 pcmbufA = F2608->pcmbuf;
1975 pcmsizeA = F2608->pcm_size;
1976 #if FM_LFO_SUPPORT
1977 LFOCnt = OPN->LFOCnt;
1978 LFOIncr = OPN->LFOIncr;
1979 if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
1980 #endif
1981 }
1982 /* update frequency counter */
1983 OPN_CALC_FCOUNT( cch[0] );
1984 OPN_CALC_FCOUNT( cch[1] );
1985 if( (State->mode & 0xc0) ){
1986 /* 3SLOT MODE */
1987 if( cch[2]->SLOT[SLOT1].Incr==-1){
1988 /* 3 slot mode */
1989 CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
1990 CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
1991 CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
1992 CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
1993 }
1994 }else OPN_CALC_FCOUNT( cch[2] );
1995 OPN_CALC_FCOUNT( cch[3] );
1996 OPN_CALC_FCOUNT( cch[4] );
1997 OPN_CALC_FCOUNT( cch[5] );
1998 /* buffering */
1999 do
2000 {
2001 #if FM_LFO_SUPPORT
2002 /* LFO */
2003 if( LFOIncr )
2004 {
2005 lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2006 lfo_pmd = lfo_amd-(LFO_RATE/2);
2007 }
2008 #endif
2009 /* clear output acc. */
2010 out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2011 /**** deltaT ADPCM ****/
2012 if( DELTAT->flag )
2013 YM_DELTAT_ADPCM_CALC(DELTAT);
2014 /* FM */
2015 for(ch = cch[0] ; ch <= cch[5] ; ch++)
2016 FM_CALC_CH( ch );
2017 for( j = 0; j < 6; j++ )
2018 {
2019 /**** ADPCM ****/
2020 if( F2608->adpcm[j].flag )
2021 #ifdef YM2608_RHYTHM_PCM
2022 YM2608_RYTHM(F2608, &F2608->adpcm[j]);
2023 #else
2024 OPNB_ADPCM_CALC_CHA( F2608, &F2608->adpcm[j]);
2025 #endif
2026 }
2027 /* buffering */
2028 FM_BUFFERING_STEREO;
2029 /* timer A controll */
2030 INTERNAL_TIMER_A( State , cch[2] )
2031 }
2032 while (--length);
2033 INTERNAL_TIMER_B(State,length)
2034 if (DELTAT->arrivedFlag) FM_STATUS_SET(State, 0x04); /* ASG */
2035
2036 #if FM_LFO_SUPPORT
2037 OPN->LFOCnt = LFOCnt;
2038 #endif
2039 }
2040
2041 /* -------------------------- YM2608(OPNA) ---------------------------------- */
YM2608Init(int num,int clock,int rate,void ** pcmrom,int * pcmsize,short * rhythmrom,int * rhythmpos,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)2042 int YM2608Init(int num, int clock, int rate,
2043 void **pcmrom,int *pcmsize,short *rhythmrom,int *rhythmpos,
2044 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2045 {
2046 int i,j;
2047
2048 if (FM2608) return (-1); /* duplicate init. */
2049 cur_chip = NULL; /* hiro-shi!! */
2050
2051 YM2608NumChips = num;
2052
2053 /* allocate extend state space */
2054 if( (FM2608 = (YM2608 *)malloc(sizeof(YM2608) * YM2608NumChips))==NULL)
2055 return (-1);
2056 /* clear */
2057 memset(FM2608,0,sizeof(YM2608) * YM2608NumChips);
2058 /* allocate total level table (128kb space) */
2059 if( !OPNInitTable() )
2060 {
2061 free( FM2608 );
2062 return (-1);
2063 }
2064
2065 for ( i = 0 ; i < YM2608NumChips; i++ ) {
2066 FM2608[i].OPN.ST.index = i;
2067 FM2608[i].OPN.type = TYPE_YM2608;
2068 FM2608[i].OPN.P_CH = FM2608[i].CH;
2069 FM2608[i].OPN.ST.clock = clock;
2070 FM2608[i].OPN.ST.rate = rate;
2071 /* FM2608[i].OPN.ST.irq = 0; */
2072 /* FM2608[i].OPN.ST.status = 0; */
2073 FM2608[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
2074 /* Extend handler */
2075 FM2608[i].OPN.ST.Timer_Handler = TimerHandler;
2076 FM2608[i].OPN.ST.IRQ_Handler = IRQHandler;
2077 /* DELTA-T */
2078 FM2608[i].deltaT.memory = (UINT8 *)(pcmrom[i]);
2079 FM2608[i].deltaT.memory_size = pcmsize[i];
2080 /* ADPCM(Rythm) */
2081 FM2608[i].pcmbuf = (UINT8 *)rhythmrom;
2082 #ifdef YM2608_RHYTHM_PCM
2083 /* rhythm sound setup (PCM) */
2084 for(j=0;j<6;j++)
2085 {
2086 /* rhythm sound */
2087 FM2608[i].adpcm[j].start = rhythmpos[j];
2088 FM2608[i].adpcm[j].end = rhythmpos[j+1]-1;
2089 }
2090 FM2608[i].pcm_size = rhythmpos[6];
2091 #else
2092 /* rhythm sound setup (ADPCM) */
2093 FM2608[i].pcm_size = rhythmsize;
2094 #endif
2095 YM2608ResetChip(i);
2096 }
2097 InitOPNB_ADPCMATable();
2098 return 0;
2099 }
2100
2101 /* ---------- shut down emurator ----------- */
YM2608Shutdown()2102 void YM2608Shutdown()
2103 {
2104 if (!FM2608) return;
2105
2106 FMCloseTable();
2107 free(FM2608);
2108 FM2608 = NULL;
2109 }
2110
2111 /* ---------- reset one of chip ---------- */
YM2608ResetChip(int num)2112 void YM2608ResetChip(int num)
2113 {
2114 int i;
2115 YM2608 *F2608 = &(FM2608[num]);
2116 FM_OPN *OPN = &(FM2608[num].OPN);
2117 YM_DELTAT *DELTAT = &(F2608[num].deltaT);
2118
2119 /* Reset Priscaler */
2120 OPNSetPris( OPN, 6*24, 6*24,4*2); /* OPN 1/6 , SSG 1/4 */
2121 /* reset SSG section */
2122 SSGReset(OPN->ST.index);
2123 /* status clear */
2124 FM_IRQMASK_SET(&OPN->ST,0x1f);
2125 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2126
2127 /* extend 3ch. disable */
2128 //OPN->type &= (~TYPE_6CH);
2129
2130 reset_channel( &OPN->ST , F2608->CH , 6 );
2131 /* reset OPerator paramater */
2132 for(i = 0xb6 ; i >= 0xb4 ; i-- )
2133 {
2134 OPNWriteReg(OPN,i ,0xc0);
2135 OPNWriteReg(OPN,i|0x100,0xc0);
2136 }
2137 for(i = 0xb2 ; i >= 0x30 ; i-- )
2138 {
2139 OPNWriteReg(OPN,i ,0);
2140 OPNWriteReg(OPN,i|0x100,0);
2141 }
2142 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2143 /* reset ADPCM unit */
2144 /**** ADPCM work initial ****/
2145 //for( i = 0; i < 6+1; i++ ){
2146 for( i = 0; i < 6; i++ ){
2147 F2608->adpcm[i].now_addr = 0;
2148 F2608->adpcm[i].now_step = 0;
2149 F2608->adpcm[i].step = 0;
2150 F2608->adpcm[i].start = 0;
2151 F2608->adpcm[i].end = 0;
2152 /* F2608->adpcm[i].delta = 21866; */
2153 F2608->adpcm[i].volume = 0;
2154 F2608->adpcm[i].pan = &out_ch[OUTD_CENTER]; /* default center */
2155 F2608->adpcm[i].flagMask = (i == 6) ? 0x20 : 0;
2156 F2608->adpcm[i].flag = 0;
2157 F2608->adpcm[i].adpcmx = 0;
2158 F2608->adpcm[i].adpcmd = 127;
2159 F2608->adpcm[i].adpcml = 0;
2160 }
2161 F2608->adpcmTL = &(TL_TABLE[0x3f*(int)(0.75/EG_STEP)]);
2162 /* F2608->port1state = -1; */
2163 F2608->adpcm_arrivedEndAddress = 0; /* don't used */
2164
2165 /* DELTA-T unit */
2166 DELTAT->freqbase = OPN->ST.freqbase;
2167 DELTAT->output_pointer = out_ch;
2168 DELTAT->portshift = 5; /* allways 5bits shift */ /* ASG */
2169 DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
2170 YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER);
2171 }
2172
2173 /* YM2608 write */
2174 /* n = number */
2175 /* a = address */
2176 /* v = value */
YM2608Write(int n,int a,UINT8 v)2177 int YM2608Write(int n, int a,UINT8 v)
2178 {
2179 YM2608 *F2608 = &(FM2608[n]);
2180 FM_OPN *OPN = &(FM2608[n].OPN);
2181 int addr;
2182
2183 switch(a&3){
2184 case 0: /* address port 0 */
2185 OPN->ST.address = v & 0xff;
2186 /* Write register to SSG emurator */
2187 if( v < 16 ) SSGWrite(n,0,v);
2188 switch(OPN->ST.address)
2189 {
2190 case 0x2d: /* divider sel */
2191 OPNSetPris( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
2192 F2608->deltaT.freqbase = OPN->ST.freqbase;
2193 break;
2194 case 0x2e: /* divider sel */
2195 OPNSetPris( OPN, 3*24, 3*24,2*2); /* OPN 1/3 , SSG 1/2 */
2196 F2608->deltaT.freqbase = OPN->ST.freqbase;
2197 break;
2198 case 0x2f: /* divider sel */
2199 OPNSetPris( OPN, 2*24, 2*24,1*2); /* OPN 1/2 , SSG 1/1 */
2200 F2608->deltaT.freqbase = OPN->ST.freqbase;
2201 break;
2202 }
2203 break;
2204 case 1: /* data port 0 */
2205 addr = OPN->ST.address;
2206 switch(addr & 0xf0)
2207 {
2208 case 0x00: /* SSG section */
2209 /* Write data to SSG emurator */
2210 SSGWrite(n,a,v);
2211 break;
2212 case 0x10: /* 0x10-0x1f : Rhythm section */
2213 #ifndef MAME_FASTSOUND
2214 YM2608UpdateReq(n);
2215 #else
2216 if (!fast_sound) YM2608UpdateReq(n);
2217 #endif
2218 FM_ADPCMAWrite(F2608,addr-0x10,v);
2219 break;
2220 case 0x20: /* Mode Register */
2221 switch(addr)
2222 {
2223 case 0x29: /* SCH,xirq mask */
2224 /* SCH,xx,xxx,EN_ZERO,EN_BRDY,EN_EOS,EN_TB,EN_TA */
2225 /* extend 3ch. enable/disable */
2226 if(v&0x80) OPN->type |= TYPE_6CH;
2227 else OPN->type &= ~TYPE_6CH;
2228 /* IRQ MASK */
2229 FM_IRQMASK_SET(&OPN->ST,v&0x1f);
2230 break;
2231 default:
2232 #ifndef MAME_FASTSOUND
2233 YM2608UpdateReq(n);
2234 #else
2235 if (!fast_sound) YM2608UpdateReq(n);
2236 #endif
2237 OPNWriteMode(OPN,addr,v);
2238 }
2239 break;
2240 default: /* OPN section */
2241 #ifndef MAME_FASTSOUND
2242 YM2608UpdateReq(n);
2243 #else
2244 if (!fast_sound) YM2608UpdateReq(n);
2245 #endif
2246 OPNWriteReg(OPN,addr,v);
2247 }
2248 break;
2249 case 2: /* address port 1 */
2250 F2608->address1 = v & 0xff;
2251 break;
2252 case 3: /* data port 1 */
2253 addr = F2608->address1;
2254 #ifndef MAME_FASTSOUND
2255 YM2608UpdateReq(n);
2256 #else
2257 if (!fast_sound) YM2608UpdateReq(n);
2258 #endif
2259 switch( addr & 0xf0 )
2260 {
2261 case 0x00: /* ADPCM PORT */
2262 switch( addr )
2263 {
2264 case 0x0c: /* Limit address L */
2265 //F2608->ADLimit = (F2608->ADLimit & 0xff00) | v;
2266 //break;
2267 case 0x0d: /* Limit address H */
2268 //F2608->ADLimit = (F2608->ADLimit & 0x00ff) | (v<<8);
2269 //break;
2270 case 0x0e: /* DAC data */
2271 //break;
2272 case 0x0f: /* PCM data port */
2273 //F2608->ADData = v;
2274 //FM_STATUS_RESET(F2608->OPN.ST,0x08);
2275 break;
2276 default:
2277 /* 0x00-0x0b */
2278 YM_DELTAT_ADPCM_Write(&F2608->deltaT,addr,v);
2279 }
2280 break;
2281 case 0x10: /* IRQ Flag controll */
2282 if( addr == 0x10 )
2283 YM2608IRQFlagWrite(&(OPN->ST),n,v);
2284 break;
2285 default:
2286 OPNWriteReg(OPN,addr|0x100,v);
2287 }
2288 }
2289 return OPN->ST.irq;
2290 }
YM2608Read(int n,int a)2291 UINT8 YM2608Read(int n,int a)
2292 {
2293 YM2608 *F2608 = &(FM2608[n]);
2294 int addr = F2608->OPN.ST.address;
2295 int ret = 0;
2296
2297 switch( a&3 ){
2298 case 0: /* status 0 : YM2203 compatible */
2299 /* BUSY:x:x:x:x:x:FLAGB:FLAGA */
2300 if(addr==0xff) ret = 0x00; /* ID code */
2301 else ret = F2608->OPN.ST.status & 0x83;
2302 break;
2303 case 1: /* status 0 */
2304 if( addr < 16 ) ret = SSGRead(n);
2305 break;
2306 case 2: /* status 1 : + ADPCM status */
2307 /* BUSY:x:PCMBUSY:ZERO:BRDY:EOS:FLAGB:FLAGA */
2308 if(addr==0xff) ret = 0x00; /* ID code */
2309 //else ret = F2608->OPN.ST.status | (F2608->adpcm[6].flag ? 0x20 : 0);
2310 else ret = F2608->OPN.ST.status | (F2608->adpcm[5].flag ? 0x20 : 0);
2311 break;
2312 case 3:
2313 ret = 0;
2314 break;
2315 }
2316 return ret;
2317 }
2318
YM2608TimerOver(int n,int c)2319 int YM2608TimerOver(int n,int c)
2320 {
2321 YM2608 *F2608 = &(FM2608[n]);
2322
2323 if( c )
2324 { /* Timer B */
2325 TimerBOver( &(F2608->OPN.ST) );
2326 }
2327 else
2328 { /* Timer A */
2329 YM2608UpdateReq(n);
2330 /* timer update */
2331 TimerAOver( &(F2608->OPN.ST) );
2332 /* CSM mode key,TL controll */
2333 if( F2608->OPN.ST.mode & 0x80 )
2334 { /* CSM mode total level latch and auto key on */
2335 CSMKeyControll( &(F2608->CH[2]) );
2336 }
2337 }
2338 return FM2608->OPN.ST.irq;
2339 }
2340
2341 #endif /* BUILD_YM2608 */
2342
2343 #if BUILD_OPNB
2344 /* -------------------------- YM2610(OPNB) ---------------------------------- */
2345 static YM2610 *FM2610=NULL; /* array of YM2610's */
2346 static int YM2610NumChips; /* total chip */
2347
2348 /* ---------- update one of chip (YM2610B FM6: ADPCM-A6: ADPCM-B:1) ----------- */
YM2610UpdateOne(int num,INT16 ** buffer,int length)2349 void YM2610UpdateOne(int num, INT16 **buffer, int length)
2350 {
2351 YM2610 *F2610 = &(FM2610[num]);
2352 FM_OPN *OPN = &(FM2610[num].OPN);
2353 YM_DELTAT *DELTAT = &(F2610[num].deltaT);
2354 int j;
2355 int ch;
2356 FMSAMPLE *bufL,*bufR;
2357
2358 /* setup DELTA-T unit */
2359 YM_DELTAT_DECODE_PRESET(DELTAT);
2360
2361 /* buffer setup */
2362 bufL = buffer[0];
2363 bufR = buffer[1];
2364
2365 if( (void *)F2610 != cur_chip ){
2366 cur_chip = (void *)F2610;
2367 State = &OPN->ST;
2368 cch[0] = &F2610->CH[1];
2369 cch[1] = &F2610->CH[2];
2370 cch[2] = &F2610->CH[4];
2371 cch[3] = &F2610->CH[5];
2372 /* setup adpcm rom address */
2373 pcmbufA = F2610->pcmbuf;
2374 pcmsizeA = F2610->pcm_size;
2375 #if FM_LFO_SUPPORT
2376 LFOCnt = OPN->LFOCnt;
2377 LFOIncr = OPN->LFOIncr;
2378 if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
2379 #endif
2380 }
2381 #ifdef YM2610B_WARNING
2382 #define FM_MSG_YM2610B "YM2610-%d.CH%d is playing,Check whether the type of the chip is YM2610B\n"
2383 /* Check YM2610B worning message */
2384 if( FM_KEY_IS(&F2610->CH[0].SLOT[3]) )
2385 LOG(LOG_WAR,(FM_MSG_YM2610B,num,0));
2386 if( FM_KEY_IS(&F2610->CH[3].SLOT[3]) )
2387 LOG(LOG_WAR,(FM_MSG_YM2610B,num,3));
2388 #endif
2389 /* update frequency counter */
2390 OPN_CALC_FCOUNT( cch[0] );
2391 if( (State->mode & 0xc0) ){
2392 /* 3SLOT MODE */
2393 if( cch[1]->SLOT[SLOT1].Incr==-1){
2394 /* 3 slot mode */
2395 CALC_FCSLOT(&cch[1]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2396 CALC_FCSLOT(&cch[1]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2397 CALC_FCSLOT(&cch[1]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2398 CALC_FCSLOT(&cch[1]->SLOT[SLOT4] , cch[1]->fc , cch[1]->kcode );
2399 }
2400 }else OPN_CALC_FCOUNT( cch[1] );
2401 OPN_CALC_FCOUNT( cch[2] );
2402 OPN_CALC_FCOUNT( cch[3] );
2403
2404 /* buffering */
2405 do
2406 {
2407 #if FM_LFO_SUPPORT
2408 /* LFO */
2409 if( LFOIncr )
2410 {
2411 lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2412 lfo_pmd = lfo_amd-(LFO_RATE/2);
2413 }
2414 #endif
2415 /* clear output acc. */
2416 out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2417 /**** deltaT ADPCM ****/
2418 if( DELTAT->flag )
2419 YM_DELTAT_ADPCM_CALC(DELTAT);
2420 /* FM */
2421 for(ch = 0 ; ch < 4 ; ch++)
2422 FM_CALC_CH( cch[ch] );
2423 for( j = 0; j < 6; j++ )
2424 {
2425 /**** ADPCM ****/
2426 if( F2610->adpcm[j].flag )
2427 OPNB_ADPCM_CALC_CHA( F2610, &F2610->adpcm[j]);
2428 }
2429 /* buffering */
2430 FM_BUFFERING_STEREO;
2431 /* timer A controll */
2432 INTERNAL_TIMER_A( State , cch[1] )
2433 }
2434 while (--length);
2435 INTERNAL_TIMER_B(State,length)
2436 #if FM_LFO_SUPPORT
2437 OPN->LFOCnt = LFOCnt;
2438 #endif
2439 }
2440 #endif /* BUILD_OPNB */
2441
2442 #if BUILD_YM2610B
2443 /* ---------- update one of chip (YM2610B FM6: ADPCM-A6: ADPCM-B:1) ----------- */
YM2610BUpdateOne(int num,INT16 ** buffer,int length)2444 void YM2610BUpdateOne(int num, INT16 **buffer, int length)
2445 {
2446 YM2610 *F2610 = &(FM2610[num]);
2447 FM_OPN *OPN = &(FM2610[num].OPN);
2448 YM_DELTAT *DELTAT = &(FM2610[num].deltaT);
2449 int j;
2450 FM_CH *ch;
2451 FMSAMPLE *bufL,*bufR;
2452
2453 /* setup DELTA-T unit */
2454 YM_DELTAT_DECODE_PRESET(DELTAT);
2455 /* buffer setup */
2456 bufL = buffer[0];
2457 bufR = buffer[1];
2458
2459 if( (void *)F2610 != cur_chip ){
2460 cur_chip = (void *)F2610;
2461 State = &OPN->ST;
2462 cch[0] = &F2610->CH[0];
2463 cch[1] = &F2610->CH[1];
2464 cch[2] = &F2610->CH[2];
2465 cch[3] = &F2610->CH[3];
2466 cch[4] = &F2610->CH[4];
2467 cch[5] = &F2610->CH[5];
2468 /* setup adpcm rom address */
2469 pcmbufA = F2610->pcmbuf;
2470 pcmsizeA = F2610->pcm_size;
2471 #if FM_LFO_SUPPORT
2472 LFOCnt = OPN->LFOCnt;
2473 LFOIncr = OPN->LFOIncr;
2474 if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
2475 #endif
2476 }
2477
2478 /* update frequency counter */
2479 OPN_CALC_FCOUNT( cch[0] );
2480 OPN_CALC_FCOUNT( cch[1] );
2481 if( (State->mode & 0xc0) ){
2482 /* 3SLOT MODE */
2483 if( cch[2]->SLOT[SLOT1].Incr==-1){
2484 /* 3 slot mode */
2485 CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2486 CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2487 CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2488 CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2489 }
2490 }else OPN_CALC_FCOUNT( cch[2] );
2491 OPN_CALC_FCOUNT( cch[3] );
2492 OPN_CALC_FCOUNT( cch[4] );
2493 OPN_CALC_FCOUNT( cch[5] );
2494
2495 /* buffering */
2496 do
2497 {
2498 #if FM_LFO_SUPPORT
2499 /* LFO */
2500 if( LFOIncr )
2501 {
2502 lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2503 lfo_pmd = lfo_amd-(LFO_RATE/2);
2504 }
2505 #endif
2506 /* clear output acc. */
2507 out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2508 /**** deltaT ADPCM ****/
2509 if( DELTAT->flag )
2510 YM_DELTAT_ADPCM_CALC(DELTAT);
2511 /* FM */
2512 for(ch = cch[0] ; ch <= cch[5] ; ch++)
2513 FM_CALC_CH( ch );
2514 for( j = 0; j < 6; j++ )
2515 {
2516 /**** ADPCM ****/
2517 if( F2610->adpcm[j].flag )
2518 OPNB_ADPCM_CALC_CHA( F2610, &F2610->adpcm[j]);
2519 }
2520 /* buffering */
2521 FM_BUFFERING_STEREO;
2522 /* timer A controll */
2523 INTERNAL_TIMER_A( State , cch[2] )
2524 }
2525 while (--length);
2526 INTERNAL_TIMER_B(State,length)
2527 #if FM_LFO_SUPPORT
2528 OPN->LFOCnt = LFOCnt;
2529 #endif
2530 }
2531 #endif /* BUILD_YM2610B */
2532
2533 #if BUILD_OPNB
YM2610Init(int num,int clock,int rate,void ** pcmroma,int * pcmsizea,void ** pcmromb,int * pcmsizeb,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)2534 int YM2610Init(int num, int clock, int rate,
2535 void **pcmroma,int *pcmsizea,void **pcmromb,int *pcmsizeb,
2536 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2537
2538 {
2539 int i;
2540
2541 if (FM2610) return (-1); /* duplicate init. */
2542 cur_chip = NULL; /* hiro-shi!! */
2543
2544 YM2610NumChips = num;
2545
2546 /* allocate extend state space */
2547 if( (FM2610 = (YM2610 *)malloc(sizeof(YM2610) * YM2610NumChips))==NULL)
2548 return (-1);
2549 /* clear */
2550 memset(FM2610,0,sizeof(YM2610) * YM2610NumChips);
2551 /* allocate total level table (128kb space) */
2552 if( !OPNInitTable() )
2553 {
2554 free( FM2610 );
2555 return (-1);
2556 }
2557
2558 for ( i = 0 ; i < YM2610NumChips; i++ ) {
2559 /* FM */
2560 FM2610[i].OPN.ST.index = i;
2561 FM2610[i].OPN.type = TYPE_YM2610;
2562 FM2610[i].OPN.P_CH = FM2610[i].CH;
2563 FM2610[i].OPN.ST.clock = clock;
2564 FM2610[i].OPN.ST.rate = rate;
2565 /* FM2610[i].OPN.ST.irq = 0; */
2566 /* FM2610[i].OPN.ST.status = 0; */
2567 FM2610[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
2568 /* Extend handler */
2569 FM2610[i].OPN.ST.Timer_Handler = TimerHandler;
2570 FM2610[i].OPN.ST.IRQ_Handler = IRQHandler;
2571 /* ADPCM */
2572 FM2610[i].pcmbuf = (UINT8 *)(pcmroma[i]);
2573 FM2610[i].pcm_size = pcmsizea[i];
2574 /* DELTA-T */
2575 FM2610[i].deltaT.memory = (UINT8 *)(pcmromb[i]);
2576 FM2610[i].deltaT.memory_size = pcmsizeb[i];
2577 /* */
2578 YM2610ResetChip(i);
2579 }
2580 InitOPNB_ADPCMATable();
2581 return 0;
2582 }
2583
2584 /* ---------- shut down emurator ----------- */
YM2610Shutdown()2585 void YM2610Shutdown()
2586 {
2587 if (!FM2610) return;
2588
2589 FMCloseTable();
2590 free(FM2610);
2591 FM2610 = NULL;
2592 }
2593
2594 /* ---------- reset one of chip ---------- */
YM2610ResetChip(int num)2595 void YM2610ResetChip(int num)
2596 {
2597 int i;
2598 YM2610 *F2610 = &(FM2610[num]);
2599 FM_OPN *OPN = &(FM2610[num].OPN);
2600 YM_DELTAT *DELTAT = &(FM2610[num].deltaT);
2601
2602 /* Reset Priscaler */
2603 OPNSetPris( OPN, 6*24, 6*24, 4*2); /* OPN 1/6 , SSG 1/4 */
2604 /* reset SSG section */
2605 SSGReset(OPN->ST.index);
2606 /* status clear */
2607 FM_IRQMASK_SET(&OPN->ST,0x03);
2608 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2609
2610 reset_channel( &OPN->ST , F2610->CH , 6 );
2611 /* reset OPerator paramater */
2612 for(i = 0xb6 ; i >= 0xb4 ; i-- )
2613 {
2614 OPNWriteReg(OPN,i ,0xc0);
2615 OPNWriteReg(OPN,i|0x100,0xc0);
2616 }
2617 for(i = 0xb2 ; i >= 0x30 ; i-- )
2618 {
2619 OPNWriteReg(OPN,i ,0);
2620 OPNWriteReg(OPN,i|0x100,0);
2621 }
2622 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2623 /**** ADPCM work initial ****/
2624 //for( i = 0; i < 6+1; i++ ){
2625 for( i = 0; i < 6; i++ ){
2626 F2610->adpcm[i].now_addr = 0;
2627 F2610->adpcm[i].now_step = 0;
2628 F2610->adpcm[i].step = 0;
2629 F2610->adpcm[i].start = 0;
2630 F2610->adpcm[i].end = 0;
2631 /* F2610->adpcm[i].delta = 21866; */
2632 F2610->adpcm[i].volume = 0;
2633 F2610->adpcm[i].pan = &out_ch[OUTD_CENTER]; /* default center */
2634 F2610->adpcm[i].flagMask = (i == 6) ? 0x80 : (1<<i);
2635 F2610->adpcm[i].flag = 0;
2636 F2610->adpcm[i].adpcmx = 0;
2637 F2610->adpcm[i].adpcmd = 127;
2638 F2610->adpcm[i].adpcml = 0;
2639 }
2640 F2610->adpcmTL = &(TL_TABLE[0x3f*(int)(0.75/EG_STEP)]);
2641 /* F2610->port1state = -1; */
2642 F2610->adpcm_arrivedEndAddress = 0;
2643
2644 /* DELTA-T unit */
2645 DELTAT->freqbase = OPN->ST.freqbase;
2646 DELTAT->output_pointer = out_ch;
2647 DELTAT->portshift = 8; /* allways 8bits shift */
2648 DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
2649 YM_DELTAT_ADPCM_Reset(DELTAT,OUTD_CENTER);
2650 }
2651
2652 /* YM2610 write */
2653 /* n = number */
2654 /* a = address */
2655 /* v = value */
YM2610Write(int n,int a,UINT8 v)2656 int YM2610Write(int n, int a,UINT8 v)
2657 {
2658 YM2610 *F2610 = &(FM2610[n]);
2659 FM_OPN *OPN = &(FM2610[n].OPN);
2660 int addr;
2661 int ch;
2662
2663 switch( a&3 ){
2664 case 0: /* address port 0 */
2665 OPN->ST.address = v & 0xff;
2666 /* Write register to SSG emurator */
2667 if( v < 16 ) SSGWrite(n,0,v);
2668 break;
2669 case 1: /* data port 0 */
2670 addr = OPN->ST.address;
2671 switch(addr & 0xf0)
2672 {
2673 case 0x00: /* SSG section */
2674 /* Write data to SSG emurator */
2675 SSGWrite(n,a,v);
2676 break;
2677 case 0x10: /* DeltaT ADPCM */
2678 #ifndef MAME_FASTSOUND
2679 YM2610UpdateReq(n);
2680 #else
2681 if (!fast_sound) YM2610UpdateReq(n);
2682 #endif
2683 switch(addr)
2684 {
2685 case 0x1c: /* FLAG CONTROL : Extend Status Clear/Mask */
2686 {
2687 UINT8 statusmask = ~v;
2688 /* set arrived flag mask */
2689 for(ch=0;ch<6;ch++)
2690 F2610->adpcm[ch].flagMask = statusmask&(1<<ch);
2691 F2610->deltaT.flagMask = statusmask&0x80;
2692 /* clear arrived flag */
2693 F2610->adpcm_arrivedEndAddress &= statusmask&0x3f;
2694 F2610->deltaT.arrivedFlag &= F2610->deltaT.flagMask;
2695 }
2696 break;
2697 default:
2698 /* 0x10-0x1b */
2699 YM_DELTAT_ADPCM_Write(&F2610->deltaT,addr-0x10,v);
2700 }
2701 break;
2702 case 0x20: /* Mode Register */
2703 #ifndef MAME_FASTSOUND
2704 YM2610UpdateReq(n);
2705 #else
2706 if (!fast_sound) YM2610UpdateReq(n);
2707 #endif
2708 OPNWriteMode(OPN,addr,v);
2709 break;
2710 default: /* OPN section */
2711 #ifndef MAME_FASTSOUND
2712 YM2610UpdateReq(n);
2713 #else
2714 if (!fast_sound) YM2610UpdateReq(n);
2715 #endif
2716 /* write register */
2717 OPNWriteReg(OPN,addr,v);
2718 }
2719 break;
2720 case 2: /* address port 1 */
2721 F2610->address1 = v & 0xff;
2722 break;
2723 case 3: /* data port 1 */
2724 #ifndef MAME_FASTSOUND
2725 YM2610UpdateReq(n);
2726 #else
2727 if (!fast_sound) YM2610UpdateReq(n);
2728 #endif
2729 addr = F2610->address1;
2730 if( addr < 0x30 )
2731 /* 100-12f : ADPCM A section */
2732 FM_ADPCMAWrite(F2610,addr,v);
2733 else
2734 OPNWriteReg(OPN,addr|0x100,v);
2735 }
2736 return OPN->ST.irq;
2737 }
YM2610Read(int n,int a)2738 UINT8 YM2610Read(int n,int a)
2739 {
2740 YM2610 *F2610 = &(FM2610[n]);
2741 int addr = F2610->OPN.ST.address;
2742 UINT8 ret = 0;
2743
2744 switch( a&3){
2745 case 0: /* status 0 : YM2203 compatible */
2746 ret = F2610->OPN.ST.status & 0x83;
2747 break;
2748 case 1: /* data 0 */
2749 if( addr < 16 ) ret = SSGRead(n);
2750 if( addr == 0xff ) ret = 0x01;
2751 break;
2752 case 2: /* status 1 : + ADPCM status */
2753 /* ADPCM STATUS (arrived End Address) */
2754 /* B,--,A5,A4,A3,A2,A1,A0 */
2755 /* B = ADPCM-B(DELTA-T) arrived end address */
2756 /* A0-A5 = ADPCM-A arrived end address */
2757 ret = F2610->adpcm_arrivedEndAddress | F2610->deltaT.arrivedFlag;
2758 break;
2759 case 3:
2760 ret = 0;
2761 break;
2762 }
2763 return ret;
2764 }
2765
YM2610TimerOver(int n,int c)2766 int YM2610TimerOver(int n,int c)
2767 {
2768 YM2610 *F2610 = &(FM2610[n]);
2769
2770 if( c )
2771 { /* Timer B */
2772 TimerBOver( &(F2610->OPN.ST) );
2773 }
2774 else
2775 { /* Timer A */
2776 YM2610UpdateReq(n);
2777 /* timer update */
2778 TimerAOver( &(F2610->OPN.ST) );
2779 /* CSM mode key,TL controll */
2780 if( F2610->OPN.ST.mode & 0x80 )
2781 { /* CSM mode total level latch and auto key on */
2782 CSMKeyControll( &(F2610->CH[2]) );
2783 }
2784 }
2785 return F2610->OPN.ST.irq;
2786 }
2787
2788 #endif /* BUILD_OPNB */
2789
2790
2791 #if BUILD_YM2612
2792 /*******************************************************************************/
2793 /* YM2612 local section */
2794 /*******************************************************************************/
2795 /* here's the virtual YM2612 */
2796 typedef struct ym2612_f {
2797 FM_OPN OPN; /* OPN state */
2798 FM_CH CH[6]; /* channel state */
2799 int address1; /* address register1 */
2800 /* dac output (YM2612) */
2801 int dacen;
2802 int dacout;
2803 } YM2612;
2804
2805 static int YM2612NumChips; /* total chip */
2806 static YM2612 *FM2612=NULL; /* array of YM2612's */
2807
2808 static int dacen;
2809
2810 /* ---------- update one of chip ----------- */
YM2612UpdateOne(int num,INT16 ** buffer,int length)2811 void YM2612UpdateOne(int num, INT16 **buffer, int length)
2812 {
2813 YM2612 *F2612 = &(FM2612[num]);
2814 FM_OPN *OPN = &(FM2612[num].OPN);
2815 FM_CH *ch,*ech;
2816 FMSAMPLE *bufL,*bufR;
2817 int dacout = F2612->dacout;
2818
2819 /* set bufer */
2820 bufL = buffer[0];
2821 bufR = buffer[1];
2822
2823 if( (void *)F2612 != cur_chip ){
2824 cur_chip = (void *)F2612;
2825
2826 State = &OPN->ST;
2827 cch[0] = &F2612->CH[0];
2828 cch[1] = &F2612->CH[1];
2829 cch[2] = &F2612->CH[2];
2830 cch[3] = &F2612->CH[3];
2831 cch[4] = &F2612->CH[4];
2832 cch[5] = &F2612->CH[5];
2833 /* DAC mode */
2834 dacen = F2612->dacen;
2835 #if FM_LFO_SUPPORT
2836 LFOCnt = OPN->LFOCnt;
2837 LFOIncr = OPN->LFOIncr;
2838 if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
2839 #endif
2840 }
2841 /* update frequency counter */
2842 OPN_CALC_FCOUNT( cch[0] );
2843 OPN_CALC_FCOUNT( cch[1] );
2844 if( (State->mode & 0xc0) ){
2845 /* 3SLOT MODE */
2846 if( cch[2]->SLOT[SLOT1].Incr==-1){
2847 /* 3 slot mode */
2848 CALC_FCSLOT(&cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] );
2849 CALC_FCSLOT(&cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] );
2850 CALC_FCSLOT(&cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] );
2851 CALC_FCSLOT(&cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode );
2852 }
2853 }else OPN_CALC_FCOUNT( cch[2] );
2854 OPN_CALC_FCOUNT( cch[3] );
2855 OPN_CALC_FCOUNT( cch[4] );
2856 OPN_CALC_FCOUNT( cch[5] );
2857
2858 ech = dacen ? cch[4] : cch[5];
2859 /* buffering */
2860 do
2861 {
2862 #if FM_LFO_SUPPORT
2863 /* LFO */
2864 if( LFOIncr )
2865 {
2866 lfo_amd = OPN_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
2867 lfo_pmd = lfo_amd-(LFO_RATE/2);
2868 }
2869 #endif
2870 /* clear output acc. */
2871 out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
2872 /* calcrate channel output */
2873 for(ch = cch[0] ; ch <= ech ; ch++)
2874 FM_CALC_CH( ch );
2875 if( dacen ) *cch[5]->connect4 += dacout;
2876 /* buffering */
2877 FM_BUFFERING_STEREO;
2878 /* timer A controll */
2879 INTERNAL_TIMER_A( State , cch[2] )
2880 }
2881 while (--length);
2882 INTERNAL_TIMER_B(State,length)
2883 #if FM_LFO_SUPPORT
2884 OPN->LFOCnt = LFOCnt;
2885 #endif
2886 }
2887
2888 /* -------------------------- YM2612 ---------------------------------- */
YM2612Init(int num,int clock,int rate,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)2889 int YM2612Init(int num, int clock, int rate,
2890 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
2891 {
2892 int i;
2893
2894 if (FM2612) return (-1); /* duplicate init. */
2895 cur_chip = NULL; /* hiro-shi!! */
2896
2897 YM2612NumChips = num;
2898
2899 /* allocate extend state space */
2900 if( (FM2612 = (YM2612 *)malloc(sizeof(YM2612) * YM2612NumChips))==NULL)
2901 return (-1);
2902 /* clear */
2903 memset(FM2612,0,sizeof(YM2612) * YM2612NumChips);
2904 /* allocate total level table (128kb space) */
2905 if( !OPNInitTable() )
2906 {
2907 free( FM2612 );
2908 return (-1);
2909 }
2910
2911 for ( i = 0 ; i < YM2612NumChips; i++ ) {
2912 FM2612[i].OPN.ST.index = i;
2913 FM2612[i].OPN.type = TYPE_YM2612;
2914 FM2612[i].OPN.P_CH = FM2612[i].CH;
2915 FM2612[i].OPN.ST.clock = clock;
2916 FM2612[i].OPN.ST.rate = rate;
2917 /* FM2612[i].OPN.ST.irq = 0; */
2918 /* FM2612[i].OPN.ST.status = 0; */
2919 FM2612[i].OPN.ST.timermodel = FM_TIMER_INTERVAL;
2920 /* Extend handler */
2921 FM2612[i].OPN.ST.Timer_Handler = TimerHandler;
2922 FM2612[i].OPN.ST.IRQ_Handler = IRQHandler;
2923 YM2612ResetChip(i);
2924 }
2925 return 0;
2926 }
2927
2928 /* ---------- shut down emurator ----------- */
YM2612Shutdown()2929 void YM2612Shutdown()
2930 {
2931 if (!FM2612) return;
2932
2933 FMCloseTable();
2934 free(FM2612);
2935 FM2612 = NULL;
2936 }
2937
2938 /* ---------- reset one of chip ---------- */
YM2612ResetChip(int num)2939 void YM2612ResetChip(int num)
2940 {
2941 int i;
2942 YM2612 *F2612 = &(FM2612[num]);
2943 FM_OPN *OPN = &(FM2612[num].OPN);
2944
2945 OPNSetPris( OPN , 12*12, 12*12, 0);
2946 /* status clear */
2947 FM_IRQMASK_SET(&OPN->ST,0x03);
2948 OPNWriteMode(OPN,0x27,0x30); /* mode 0 , timer reset */
2949
2950 reset_channel( &OPN->ST , &F2612->CH[0] , 6 );
2951
2952 for(i = 0xb6 ; i >= 0xb4 ; i-- )
2953 {
2954 OPNWriteReg(OPN,i ,0xc0);
2955 OPNWriteReg(OPN,i|0x100,0xc0);
2956 }
2957 for(i = 0xb2 ; i >= 0x30 ; i-- )
2958 {
2959 OPNWriteReg(OPN,i ,0);
2960 OPNWriteReg(OPN,i|0x100,0);
2961 }
2962 for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(OPN,i,0);
2963 /* DAC mode clear */
2964 F2612->dacen = 0;
2965 }
2966
2967 /* YM2612 write */
2968 /* n = number */
2969 /* a = address */
2970 /* v = value */
YM2612Write(int n,int a,UINT8 v)2971 int YM2612Write(int n, int a,UINT8 v)
2972 {
2973 YM2612 *F2612 = &(FM2612[n]);
2974 int addr;
2975
2976 switch( a&3){
2977 case 0: /* address port 0 */
2978 F2612->OPN.ST.address = v & 0xff;
2979 break;
2980 case 1: /* data port 0 */
2981 addr = F2612->OPN.ST.address;
2982 switch( addr & 0xf0 )
2983 {
2984 case 0x20: /* 0x20-0x2f Mode */
2985 switch( addr )
2986 {
2987 case 0x2a: /* DAC data (YM2612) */
2988 #ifndef MAME_FASTSOUND
2989 YM2612UpdateReq(n);
2990 #else
2991 if (!fast_sound) YM2612UpdateReq(n);
2992 #endif
2993 F2612->dacout = ((int)v - 0x80)<<(TL_BITS-7);
2994 break;
2995 case 0x2b: /* DAC Sel (YM2612) */
2996 /* b7 = dac enable */
2997 F2612->dacen = v & 0x80;
2998 cur_chip = NULL;
2999 break;
3000 default: /* OPN section */
3001 #ifndef MAME_FASTSOUND
3002 YM2612UpdateReq(n);
3003 #else
3004 if (!fast_sound) YM2612UpdateReq(n);
3005 #endif
3006 /* write register */
3007 OPNWriteMode(&(F2612->OPN),addr,v);
3008 }
3009 break;
3010 default: /* 0x30-0xff OPN section */
3011 #ifndef MAME_FASTSOUND
3012 YM2612UpdateReq(n);
3013 #else
3014 if (!fast_sound) YM2612UpdateReq(n);
3015 #endif
3016 /* write register */
3017 OPNWriteReg(&(F2612->OPN),addr,v);
3018 }
3019 break;
3020 case 2: /* address port 1 */
3021 F2612->address1 = v & 0xff;
3022 break;
3023 case 3: /* data port 1 */
3024 addr = F2612->address1;
3025 #ifndef MAME_FASTSOUND
3026 YM2612UpdateReq(n);
3027 #else
3028 if (!fast_sound) YM2612UpdateReq(n);
3029 #endif
3030 OPNWriteReg(&(F2612->OPN),addr|0x100,v);
3031 break;
3032 }
3033 return F2612->OPN.ST.irq;
3034 }
YM2612Read(int n,int a)3035 UINT8 YM2612Read(int n,int a)
3036 {
3037 YM2612 *F2612 = &(FM2612[n]);
3038
3039 switch( a&3){
3040 case 0: /* status 0 */
3041 return F2612->OPN.ST.status;
3042 case 1:
3043 case 2:
3044 case 3:
3045 LOG(LOG_WAR,("YM2612 #%d:A=%d read unmapped area\n"));
3046 return F2612->OPN.ST.status;
3047 }
3048 return 0;
3049 }
3050
YM2612TimerOver(int n,int c)3051 int YM2612TimerOver(int n,int c)
3052 {
3053 YM2612 *F2612 = &(FM2612[n]);
3054
3055 if( c )
3056 { /* Timer B */
3057 TimerBOver( &(F2612->OPN.ST) );
3058 }
3059 else
3060 { /* Timer A */
3061 YM2612UpdateReq(n);
3062 /* timer update */
3063 TimerAOver( &(F2612->OPN.ST) );
3064 /* CSM mode key,TL controll */
3065 if( F2612->OPN.ST.mode & 0x80 )
3066 { /* CSM mode total level latch and auto key on */
3067 CSMKeyControll( &(F2612->CH[2]) );
3068 }
3069 }
3070 return F2612->OPN.ST.irq;
3071 }
3072
3073 #endif /* BUILD_YM2612 */
3074
3075
3076 #if BUILD_YM2151
3077 /*******************************************************************************/
3078 /* YM2151 local section */
3079 /*******************************************************************************/
3080 /* -------------------------- OPM ---------------------------------- */
3081 #undef FM_SEG_SUPPORT
3082 #define FM_SEG_SUPPORT 0 /* OPM has not SEG type envelope */
3083
3084 /* here's the virtual YM2151(OPM) */
3085 typedef struct ym2151_f {
3086 FM_ST ST; /* general state */
3087 FM_CH CH[8]; /* channel state */
3088 UINT8 ct; /* CT0,1 */
3089 UINT32 NoiseCnt; /* noise generator */
3090 UINT32 NoiseIncr; /* noise mode enable & step */
3091 #if FM_LFO_SUPPORT
3092 /* LFO */
3093 UINT32 LFOCnt;
3094 UINT32 LFOIncr;
3095 UINT8 pmd; /* LFO pmd level */
3096 UINT8 amd; /* LFO amd level */
3097 INT32 *wavetype; /* LFO waveform */
3098 UINT8 testreg; /* test register (LFO reset) */
3099 #endif
3100 UINT32 KC_TABLE[8*12*64+950];/* keycode,keyfunction -> count */
3101 mem_write_handler PortWrite;/* callback when write CT0/CT1 */
3102 } YM2151;
3103
3104 static YM2151 *FMOPM=NULL; /* array of YM2151's */
3105 static int YM2151NumChips; /* total chip */
3106
3107 #if FM_LFO_SUPPORT
3108 static INT32 OPM_LFO_waves[LFO_ENT*4]; /* LFO wave tabel */
3109 static INT32 *OPM_LFO_wave;
3110 #endif
3111
3112 /* current chip state */
3113 static UINT32 NoiseCnt , NoiseIncr;
3114
3115 static INT32 *NOISE_TABLE[SIN_ENT];
3116
3117 static const int DT2_TABLE[4]={ /* 4 DT2 values */
3118 /*
3119 * DT2 defines offset in cents from base note
3120 *
3121 * The table below defines offset in deltas table...
3122 * User's Manual page 22
3123 * Values below were calculated using formula: value = orig.val * 1.5625
3124 *
3125 * DT2=0 DT2=1 DT2=2 DT2=3
3126 * 0 600 781 950
3127 */
3128 0, 384, 500, 608
3129 };
3130
3131 static const int KC_TO_SEMITONE[16]={
3132 /*translate note code KC into more usable number of semitone*/
3133 0*64, 1*64, 2*64, 3*64,
3134 3*64, 4*64, 5*64, 6*64,
3135 6*64, 7*64, 8*64, 9*64,
3136 9*64,10*64,11*64,12*64
3137 };
3138
3139 /* ---------- frequency counter ---------- */
OPM_CALC_FCOUNT(YM2151 * OPM,FM_CH * CH)3140 static INLINE void OPM_CALC_FCOUNT(YM2151 *OPM , FM_CH *CH )
3141 {
3142 if( CH->SLOT[SLOT1].Incr==-1)
3143 {
3144 int fc = CH->fc;
3145 int kc = CH->kcode;
3146
3147 CALC_FCSLOT(&CH->SLOT[SLOT1] , OPM->KC_TABLE[fc + CH->SLOT[SLOT1].DT2] , kc );
3148 CALC_FCSLOT(&CH->SLOT[SLOT2] , OPM->KC_TABLE[fc + CH->SLOT[SLOT2].DT2] , kc );
3149 CALC_FCSLOT(&CH->SLOT[SLOT3] , OPM->KC_TABLE[fc + CH->SLOT[SLOT3].DT2] , kc );
3150 CALC_FCSLOT(&CH->SLOT[SLOT4] , OPM->KC_TABLE[fc + CH->SLOT[SLOT4].DT2] , kc );
3151 }
3152 }
3153
3154 /* ---------- calcrate one of channel7 ---------- */
OPM_CALC_CH7(FM_CH * CH)3155 static INLINE void OPM_CALC_CH7( FM_CH *CH )
3156 {
3157 UINT32 eg_out1,eg_out2,eg_out3,eg_out4; //envelope output
3158
3159 /* Phase Generator */
3160 #if FM_LFO_SUPPORT
3161 INT32 pms = lfo_pmd * CH->pms / LFO_RATE;
3162 if(pms)
3163 {
3164 pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr + (INT32)(pms * CH->SLOT[SLOT1].Incr) / PMS_RATE);
3165 pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr + (INT32)(pms * CH->SLOT[SLOT2].Incr) / PMS_RATE);
3166 pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr + (INT32)(pms * CH->SLOT[SLOT3].Incr) / PMS_RATE);
3167 pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr + (INT32)(pms * CH->SLOT[SLOT4].Incr) / PMS_RATE);
3168 }
3169 else
3170 #endif
3171 {
3172 pg_in1 = (CH->SLOT[SLOT1].Cnt += CH->SLOT[SLOT1].Incr);
3173 pg_in2 = (CH->SLOT[SLOT2].Cnt += CH->SLOT[SLOT2].Incr);
3174 pg_in3 = (CH->SLOT[SLOT3].Cnt += CH->SLOT[SLOT3].Incr);
3175 pg_in4 = (CH->SLOT[SLOT4].Cnt += CH->SLOT[SLOT4].Incr);
3176 }
3177 /* Envelope Generator */
3178 FM_CALC_EG(eg_out1,CH->SLOT[SLOT1]);
3179 FM_CALC_EG(eg_out2,CH->SLOT[SLOT2]);
3180 FM_CALC_EG(eg_out3,CH->SLOT[SLOT3]);
3181 FM_CALC_EG(eg_out4,CH->SLOT[SLOT4]);
3182
3183 /* connection */
3184 if( eg_out1 < EG_CUT_OFF ) /* SLOT 1 */
3185 {
3186 if( CH->FB ){
3187 /* with self feed back */
3188 pg_in1 += (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
3189 CH->op1_out[1] = CH->op1_out[0];
3190 }
3191 CH->op1_out[0] = OP_OUT(pg_in1,eg_out1);
3192 /* output slot1 */
3193 if( !CH->connect1 )
3194 {
3195 /* algorythm 5 */
3196 pg_in2 += CH->op1_out[0];
3197 pg_in3 += CH->op1_out[0];
3198 pg_in4 += CH->op1_out[0];
3199 }else{
3200 /* other algorythm */
3201 *CH->connect1 += CH->op1_out[0];
3202 }
3203 }
3204 if( eg_out2 < EG_CUT_OFF ) /* SLOT 2 */
3205 *CH->connect2 += OP_OUT(pg_in2,eg_out2);
3206 if( eg_out3 < EG_CUT_OFF ) /* SLOT 3 */
3207 *CH->connect3 += OP_OUT(pg_in3,eg_out3);
3208 /* SLOT 4 */
3209 if(NoiseIncr)
3210 {
3211 NoiseCnt += NoiseIncr;
3212 if( eg_out4 < EG_CUT_OFF )
3213 *CH->connect4 += OP_OUTN(NoiseCnt,eg_out4);
3214 }
3215 else
3216 {
3217 if( eg_out4 < EG_CUT_OFF )
3218 *CH->connect4 += OP_OUT(pg_in4,eg_out4);
3219 }
3220 }
3221
OPMInitTable(void)3222 static int OPMInitTable(void)
3223 {
3224 int i;
3225
3226 /* NOISE wave table */
3227 for(i=0;i<SIN_ENT;i++)
3228 {
3229 int sign = rand()&1 ? TL_MAX : 0;
3230 int lev = rand()&0x1ff;
3231 //pom = lev ? 20*log10(0x200/lev) : 0; /* decibel */
3232 //NOISE_TABLE[i] = &TL_TABLE[sign + (int)(pom / EG_STEP)]; /* TL_TABLE steps */
3233 NOISE_TABLE[i] = &TL_TABLE[sign + lev * EG_ENT/0x200]; /* TL_TABLE steps */
3234 }
3235
3236 #if FM_LFO_SUPPORT
3237 /* LFO wave tables , 4 pattern */
3238 for(i=0;i<LFO_ENT;i++)
3239 {
3240 OPM_LFO_waves[ i]= LFO_RATE * i / LFO_ENT /127;
3241 OPM_LFO_waves[LFO_ENT +i]= ( i<LFO_ENT/2 ? 0 : LFO_RATE )/127;
3242 OPM_LFO_waves[LFO_ENT*2+i]= LFO_RATE* (i<LFO_ENT/2 ? i : LFO_ENT-i) /(LFO_ENT/2) /127;
3243 OPM_LFO_waves[LFO_ENT*3+i]= LFO_RATE * (rand()&0xff) /256 /127;
3244 }
3245 #endif
3246 return FMInitTable();
3247 }
3248
3249 /* ---------- priscaler set(and make time tables) ---------- */
OPMResetTable(int num)3250 static void OPMResetTable( int num )
3251 {
3252 YM2151 *OPM = &(FMOPM[num]);
3253 int i;
3254 float pom;
3255 float rate;
3256
3257 if (FMOPM[num].ST.rate)
3258 {
3259 #ifndef MAME_FASTSOUND
3260 rate = (float)(1<<FREQ_BITS) / (3579545.0 / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
3261 #else
3262 if (fast_sound)
3263 rate = (float)(1<<FREQ_BITS) / ((3579545.0/2.0) / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
3264 else
3265 rate = (float)(1<<FREQ_BITS) / (3579545.0 / FMOPM[num].ST.clock * FMOPM[num].ST.rate);
3266 #endif
3267 }
3268 else rate = 1;
3269
3270 for (i=0; i<8*12*64+950; i++)
3271 {
3272 /* This calculation type was used from the Jarek's YM2151 emulator */
3273 pom = 6.875 * pow (2, ((i+4*64)*1.5625/1200.0) ); /*13.75Hz is note A 12semitones below A-0, so D#0 is 4 semitones above then*/
3274 /*calculate phase increment for above precounted Hertz value*/
3275 OPM->KC_TABLE[i] = (UINT32)(pom * rate);
3276 /*LOG(LOG_WAR,("OPM KC %d = %x\n",i,OPM->KC_TABLE[i]));*/
3277 }
3278
3279 /* make time tables */
3280 init_timetables( &OPM->ST , OPM_DTTABLE , OPM_ARRATE , OPM_DRRATE );
3281
3282 }
3283
3284 /* ---------- write a register on YM2151 chip number 'n' ---------- */
OPMWriteReg(int n,int r,int v)3285 static void OPMWriteReg(int n, int r, int v)
3286 {
3287 UINT8 c;
3288 FM_CH *CH;
3289 FM_SLOT *SLOT;
3290
3291 YM2151 *OPM = &(FMOPM[n]);
3292
3293 c = OPM_CHAN(r);
3294 CH = &OPM->CH[c];
3295 SLOT= &CH->SLOT[OPM_SLOT(r)];
3296
3297 switch( r & 0xe0 ){
3298 case 0x00: /* 0x00-0x1f */
3299 switch( r ){
3300 #if FM_LFO_SUPPORT
3301 case 0x01: /* test */
3302 if( (OPM->testreg&(OPM->testreg^v))&0x02 ) /* fall eggge */
3303 { /* reset LFO counter */
3304 OPM->LFOCnt = 0;
3305 cur_chip = NULL;
3306 }
3307 OPM->testreg = v;
3308 break;
3309 #endif
3310 case 0x08: /* key on / off */
3311 c = v&7;
3312 /* CSM mode */
3313 if( OPM->ST.mode & 0x80 ) break;
3314 CH = &OPM->CH[c];
3315 if(v&0x08) FM_KEYON(CH,SLOT1); else FM_KEYOFF(CH,SLOT1);
3316 if(v&0x10) FM_KEYON(CH,SLOT2); else FM_KEYOFF(CH,SLOT2);
3317 if(v&0x20) FM_KEYON(CH,SLOT3); else FM_KEYOFF(CH,SLOT3);
3318 if(v&0x40) FM_KEYON(CH,SLOT4); else FM_KEYOFF(CH,SLOT4);
3319 break;
3320 case 0x0f: /* Noise freq (ch7.op4) */
3321 /* b7 = Noise enable */
3322 /* b0-4 noise freq */
3323 OPM->NoiseIncr = !(v&0x80) ? 0 :
3324 /* !!!!! unknown noise freqency rate !!!!! */
3325 (UINT32)((1<<FREQ_BITS) / 65536 * (v&0x1f) * OPM->ST.freqbase);
3326 cur_chip = NULL;
3327 #if 1
3328 if( v & 0x80 ){
3329 LOG(LOG_WAR,("OPM Noise mode selelted\n"));
3330 }
3331 #endif
3332 break;
3333 case 0x10: /* timer A High 8*/
3334 OPM->ST.TA = (OPM->ST.TA & 0x03)|(((int)v)<<2);
3335 break;
3336 case 0x11: /* timer A Low 2*/
3337 OPM->ST.TA = (OPM->ST.TA & 0x3fc)|(v&3);
3338 break;
3339 case 0x12: /* timer B */
3340 OPM->ST.TB = v;
3341 break;
3342 case 0x14: /* mode , timer controll */
3343 FMSetMode( &(OPM->ST),n,v );
3344 break;
3345 #if FM_LFO_SUPPORT
3346 case 0x18: /* lfreq */
3347 /* f = fm * 2^(LFRQ/16) / (4295*10^6) */
3348 {
3349 static float drate[16]={
3350 1.0 ,1.044273782,1.090507733,1.138788635, //0-3
3351 1.189207115,1.241857812,1.296839555,1.354255547, //4-7
3352 1.414213562,1.476826146,1.542210825,1.610490332, //8-11
3353 1.681792831,1.75625216 ,1.834008086,1.915206561};
3354 float rate = pow(2.0,v/16)*drate[v&0x0f] / 4295000000.0;
3355 OPM->LFOIncr = (UINT32)((float)LFO_ENT*(1<<LFO_SHIFT) * (OPM->ST.freqbase*64) * rate);
3356 cur_chip = NULL;
3357 }
3358 break;
3359 case 0x19: /* PMD/AMD */
3360 if( v & 0x80 ) OPM->pmd = v & 0x7f;
3361 else OPM->amd = v & 0x7f;
3362 break;
3363 #endif
3364 case 0x1b: /* CT , W */
3365 /* b7 = CT1 */
3366 /* b6 = CT0 */
3367 /* b0-2 = wave form(LFO) 0=nokogiri,1=houkei,2=sankaku,3=noise */
3368 //if(OPM->ct != v)
3369 {
3370 OPM->ct = v>>6;
3371 if( OPM->PortWrite != 0)
3372 OPM->PortWrite(0, OPM->ct ); /* bit0 = CT0,bit1 = CT1 */
3373 }
3374 #if FM_LFO_SUPPORT
3375 if( OPM->wavetype != &OPM_LFO_waves[(v&3)*LFO_ENT])
3376 {
3377 OPM->wavetype = &OPM_LFO_waves[(v&3)*LFO_ENT];
3378 cur_chip = NULL;
3379 }
3380 #endif
3381 break;
3382 }
3383 break;
3384 case 0x20: /* 20-3f */
3385 switch( OPM_SLOT(r) ){
3386 case 0: /* 0x20-0x27 : RL,FB,CON */
3387 {
3388 int feedback = (v>>3)&7;
3389 CH->ALGO = v&7;
3390 CH->FB = feedback ? 8+1 - feedback : 0;
3391 /* RL order -> LR order */
3392 CH->PAN = ((v>>7)&1) | ((v>>5)&2);
3393 setup_connection( CH );
3394 }
3395 break;
3396 case 1: /* 0x28-0x2f : Keycode */
3397 {
3398 int blk = (v>>4)&7;
3399 /* make keyscale code */
3400 CH->kcode = (v>>2)&0x1f;
3401 /* make basic increment counter 22bit = 1 cycle */
3402 CH->fc = (blk * (12*64)) + KC_TO_SEMITONE[v&0x0f] + CH->fn_h;
3403 CH->SLOT[SLOT1].Incr=-1;
3404 }
3405 break;
3406 case 2: /* 0x30-0x37 : Keyfunction */
3407 CH->fc -= CH->fn_h;
3408 CH->fn_h = v>>2;
3409 CH->fc += CH->fn_h;
3410 CH->SLOT[SLOT1].Incr=-1;
3411 break;
3412 #if FM_LFO_SUPPORT
3413 case 3: /* 0x38-0x3f : PMS / AMS */
3414 /* b0-1 AMS */
3415 /* AMS * 23.90625db @ AMD=127 */
3416 //CH->ams = (v & 0x03) * (23.90625/EG_STEP);
3417 CH->ams = (UINT32)( (23.90625/EG_STEP) / (1<<(3-(v&3))) );
3418 CH->SLOT[SLOT1].ams = CH->ams * CH->SLOT[SLOT1].amon;
3419 CH->SLOT[SLOT2].ams = CH->ams * CH->SLOT[SLOT2].amon;
3420 CH->SLOT[SLOT3].ams = CH->ams * CH->SLOT[SLOT3].amon;
3421 CH->SLOT[SLOT4].ams = CH->ams * CH->SLOT[SLOT4].amon;
3422 /* b4-6 PMS */
3423 /* 0,5,10,20,50,100,400,700 (cent) @ PMD=127 */
3424 {
3425 /* 1 octabe = 1200cent = +100%/-50% */
3426 /* 100cent = 1seminote = 6% ?? */
3427 static const int pmd_table[8] = {0,5,10,20,50,100,400,700};
3428 CH->pms = (INT32)( (1.5/1200.0)*pmd_table[(v>>4) & 0x07] * PMS_RATE );
3429 }
3430 break;
3431 #endif
3432 }
3433 break;
3434 case 0x40: /* DT1,MUL */
3435 set_det_mul(&OPM->ST,CH,SLOT,v);
3436 break;
3437 case 0x60: /* TL */
3438 set_tl(CH,SLOT,v,(OPM->ST.mode & 0x80) );
3439 break;
3440 case 0x80: /* KS, AR */
3441 set_ar_ksr(CH,SLOT,v,OPM->ST.AR_TABLE);
3442 break;
3443 case 0xa0: /* AMS EN,D1R */
3444 set_dr(SLOT,v,OPM->ST.DR_TABLE);
3445 #if FM_LFO_SUPPORT
3446 /* bit7 = AMS ENABLE */
3447 SLOT->amon = v>>7;
3448 SLOT->ams = CH->ams * SLOT->amon;
3449 #endif
3450 break;
3451 case 0xc0: /* DT2 ,D2R */
3452 SLOT->DT2 = DT2_TABLE[v>>6];
3453 CH->SLOT[SLOT1].Incr=-1;
3454 set_sr(SLOT,v,OPM->ST.DR_TABLE);
3455 break;
3456 case 0xe0: /* D1L, RR */
3457 set_sl_rr(SLOT,v,OPM->ST.DR_TABLE);
3458 break;
3459 }
3460 }
3461
YM2151Write(int n,int a,UINT8 v)3462 int YM2151Write(int n,int a,UINT8 v)
3463 {
3464 YM2151 *F2151 = &(FMOPM[n]);
3465
3466 if( !(a&1) )
3467 { /* address port */
3468 F2151->ST.address = v & 0xff;
3469 }
3470 else
3471 { /* data port */
3472 int addr = F2151->ST.address;
3473 #ifndef MAME_FASTSOUND
3474 YM2151UpdateReq(n);
3475 #else
3476 if (!fast_sound) YM2151UpdateReq(n);
3477 #endif
3478 /* write register */
3479 OPMWriteReg(n,addr,v);
3480 }
3481 return F2151->ST.irq;
3482 }
3483
3484 /* ---------- reset one of chip ---------- */
OPMResetChip(int num)3485 void OPMResetChip(int num)
3486 {
3487 int i;
3488 YM2151 *OPM = &(FMOPM[num]);
3489
3490 OPMResetTable( num );
3491 reset_channel( &OPM->ST , &OPM->CH[0] , 8 );
3492 /* status clear */
3493 FM_IRQMASK_SET(&OPM->ST,0x03);
3494 OPMWriteReg(num,0x1b,0x00);
3495 /* reset OPerator paramater */
3496 for(i = 0xff ; i >= 0x20 ; i-- ) OPMWriteReg(num,i,0);
3497 }
3498
3499 /* ---------- Initialize YM2151 emulator(s) ---------- */
3500 /* 'num' is the number of virtual YM2151's to allocate */
3501 /* 'rate' is sampling rate and 'bufsiz' is the size of the */
3502 /* buffer that should be updated at each interval */
OPMInit(int num,int clock,int rate,FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)3503 int OPMInit(int num, int clock, int rate,
3504 FM_TIMERHANDLER TimerHandler,FM_IRQHANDLER IRQHandler)
3505 {
3506 int i;
3507
3508 if (FMOPM) return (-1); /* duplicate init. */
3509 cur_chip = NULL; /* hiro-shi!! */
3510
3511 YM2151NumChips = num;
3512
3513 /* allocate ym2151 state space */
3514 if( (FMOPM = (YM2151 *)malloc(sizeof(YM2151) * YM2151NumChips))==NULL)
3515 return (-1);
3516
3517 /* clear */
3518 memset(FMOPM,0,sizeof(YM2151) * YM2151NumChips);
3519
3520 /* allocate total lebel table (128kb space) */
3521 if( !OPMInitTable() )
3522 {
3523 free( FMOPM );
3524 return (-1);
3525 }
3526 for ( i = 0 ; i < YM2151NumChips; i++ ) {
3527 FMOPM[i].ST.index = i;
3528 FMOPM[i].ST.clock = clock;
3529 FMOPM[i].ST.rate = rate;
3530 /* FMOPM[i].ST.irq = 0; */
3531 /* FMOPM[i].ST.status = 0; */
3532 FMOPM[i].ST.timermodel = FM_TIMER_INTERVAL;
3533 FMOPM[i].ST.freqbase = rate ? ((float)clock / rate) / 64 : 0;
3534 FMOPM[i].ST.TimerBase = (float)TIME_ONE_SEC/((float)clock / 64.0);
3535 /* Extend handler */
3536 FMOPM[i].ST.Timer_Handler = TimerHandler;
3537 FMOPM[i].ST.IRQ_Handler = IRQHandler;
3538 /* Reset callback handler of CT0/1 */
3539 FMOPM[i].PortWrite = 0;
3540 OPMResetChip(i);
3541 }
3542 return(0);
3543 }
3544
3545 /* ---------- shut down emurator ----------- */
OPMShutdown()3546 void OPMShutdown()
3547 {
3548 if (!FMOPM) return;
3549
3550 FMCloseTable();
3551 free(FMOPM);
3552 FMOPM = NULL;
3553 }
3554
YM2151Read(int n,int a)3555 UINT8 YM2151Read(int n,int a)
3556 {
3557 if( !(a&1) ) return 0;
3558 else return FMOPM[n].ST.status;
3559 }
3560
3561 /* ---------- make digital sound data ---------- */
OPMUpdateOne(int num,INT16 ** buffer,int length)3562 void OPMUpdateOne(int num, INT16 **buffer, int length)
3563 {
3564 YM2151 *OPM = &(FMOPM[num]);
3565 int amd,pmd;
3566 FM_CH *ch;
3567 FMSAMPLE *bufL,*bufR;
3568
3569 /* set bufer */
3570 bufL = buffer[0];
3571 bufR = buffer[1];
3572
3573 if( (void *)OPM != cur_chip ){
3574 cur_chip = (void *)OPM;
3575
3576 State = &OPM->ST;
3577 /* channel pointer */
3578 cch[0] = &OPM->CH[0];
3579 cch[1] = &OPM->CH[1];
3580 cch[2] = &OPM->CH[2];
3581 cch[3] = &OPM->CH[3];
3582 cch[4] = &OPM->CH[4];
3583 cch[5] = &OPM->CH[5];
3584 cch[6] = &OPM->CH[6];
3585 cch[7] = &OPM->CH[7];
3586 /* ch7.op4 noise mode / step */
3587 NoiseIncr = OPM->NoiseIncr;
3588 NoiseCnt = OPM->NoiseCnt;
3589 #if FM_LFO_SUPPORT
3590 /* LFO */
3591 LFOCnt = OPM->LFOCnt;
3592 //LFOIncr = OPM->LFOIncr;
3593 if( !LFOIncr ) lfo_amd = lfo_pmd = 0;
3594 OPM_LFO_wave = OPM->wavetype;
3595 #endif
3596 }
3597 amd = OPM->amd;
3598 pmd = OPM->pmd;
3599 if(amd==0 && pmd==0)
3600 LFOIncr = 0;
3601 else
3602 LFOIncr = OPM->LFOIncr;
3603
3604 OPM_CALC_FCOUNT( OPM , cch[0] );
3605 OPM_CALC_FCOUNT( OPM , cch[1] );
3606 OPM_CALC_FCOUNT( OPM , cch[2] );
3607 OPM_CALC_FCOUNT( OPM , cch[3] );
3608 OPM_CALC_FCOUNT( OPM , cch[4] );
3609 OPM_CALC_FCOUNT( OPM , cch[5] );
3610 OPM_CALC_FCOUNT( OPM , cch[6] );
3611 OPM_CALC_FCOUNT( OPM , cch[7] );
3612
3613 do
3614 {
3615 #if FM_LFO_SUPPORT
3616 /* LFO */
3617 if( LFOIncr )
3618 {
3619 INT32 depth = OPM_LFO_wave[(LFOCnt+=LFOIncr)>>LFO_SHIFT];
3620 lfo_amd = depth * amd;
3621 lfo_pmd = (depth-(LFO_RATE/127/2)) * pmd;
3622 }
3623 #endif
3624 /* clear output acc. */
3625 out_ch[OUTD_LEFT] = out_ch[OUTD_RIGHT]= out_ch[OUTD_CENTER] = 0;
3626 /* calcrate channel output */
3627 for(ch = cch[0] ; ch <= cch[6] ; ch++)
3628 FM_CALC_CH( ch );
3629 OPM_CALC_CH7( cch[7] );
3630 /* buffering */
3631 FM_BUFFERING_STEREO;
3632 /* timer A controll */
3633 INTERNAL_TIMER_A( State , cch[7] )
3634 }
3635 while (--length);
3636 INTERNAL_TIMER_B(State,length)
3637 OPM->NoiseCnt = NoiseCnt;
3638 #if FM_LFO_SUPPORT
3639 OPM->LFOCnt = LFOCnt;
3640 #endif
3641 }
3642
OPMSetPortHander(int n,mem_write_handler PortWrite)3643 void OPMSetPortHander(int n,mem_write_handler PortWrite)
3644 {
3645 FMOPM[n].PortWrite = PortWrite;
3646 }
3647
YM2151TimerOver(int n,int c)3648 int YM2151TimerOver(int n,int c)
3649 {
3650 YM2151 *F2151 = &(FMOPM[n]);
3651
3652 if( c )
3653 { /* Timer B */
3654 TimerBOver( &(F2151->ST) );
3655 }
3656 else
3657 { /* Timer A */
3658 YM2151UpdateReq(n);
3659 /* timer update */
3660 TimerAOver( &(F2151->ST) );
3661 /* CSM mode key,TL controll */
3662 if( F2151->ST.mode & 0x80 )
3663 { /* CSM mode total level latch and auto key on */
3664 CSMKeyControll( &(F2151->CH[0]) );
3665 CSMKeyControll( &(F2151->CH[1]) );
3666 CSMKeyControll( &(F2151->CH[2]) );
3667 CSMKeyControll( &(F2151->CH[3]) );
3668 CSMKeyControll( &(F2151->CH[4]) );
3669 CSMKeyControll( &(F2151->CH[5]) );
3670 CSMKeyControll( &(F2151->CH[6]) );
3671 CSMKeyControll( &(F2151->CH[7]) );
3672 }
3673 }
3674 return F2151->ST.irq;
3675 }
3676
3677 #endif /* BUILD_YM2151 */
3678