1 #define YM2610B_WARNING
3 /* YM2608 rhythm data is PCM ,not an ADPCM */
4 #define YM2608_RHYTHM_PCM
8 ** File: fm.c -- software implementation of FM sound generator
10 ** Copyright (C) 1998 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
17 **** change log. (hiro-shi) ****
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).
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.
39 YM2612 DAC output mode
40 YM2151 CSM speech mode
42 status busy flag (already not busy)
43 LFO contoller (YM2612/YM2610/YM2608/YM2151)
45 YM2608 DELTA-T-ADPCM and RYTHM
46 YM2610 DELTA-T-ADPCM with PCM port
47 YM2610 PCM memory data access
49 YM2608 status mask (register :0x110)
51 key scale level rate (?)
52 attack rate time rate , curve (?)
53 decay rate time rate , curve (?)
54 self feedback calcration
55 YM2610 ADPCM mixing level
60 fnum fMus * 2^20 / (fM/(12*n))
61 TimerOverA (12*n)*(1024-NA)/fFM 64*(1024-Na)/fm
62 TimerOverB (12*n)*(256-NB)/fFM 1024*(256-Nb)/fm
63 output bits 10bit<<3bit 16bit * 2ch (YM3012=10bit<<3bit)
64 sampling rate fFM / (12*6) ? fFM / 64
65 lfo freq ( fM*2^(LFRQ/16) ) / (4295*10^6)
68 /************************************************************************/
69 /* comment of hiro-shi(Hiromitsu Shioya) */
70 /* YM2610(B) = (OPN-B */
71 /* YM2610 : PSG:3ch FM:4ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
72 /* YM2610B : PSG:3ch FM:6ch ADPCM(18.5KHz):6ch DeltaT ADPCM:1ch */
73 /************************************************************************/
75 //#define INLINE __inline__
87 #define PI 3.14159265357989
90 /***** shared function building option ****/
91 #define BUILD_OPN (BUILD_YM2203||BUILD_YM2608||BUILD_YM2610||BUILD_YM2612)
92 #define BUILD_OPNB (BUILD_YM2610||BUILD_YM2610B)
93 #define BUILD_FM_ADPCMA (BUILD_YM2608||BUILD_YM2610)
94 #define BUILD_FM_ADPCMB (BUILD_YM2608||BUILD_YM2610)
96 /**** YM2610 ADPCM defines ****/
97 #define ADPCMA_VOLUME_RATE (1)
98 #define ADPCMB_VOLUME_RATE (2) /* DELTA-T volume rate */
100 #define ADPCM_SHIFT (16)
102 //#define AUDIO_CONV(A) ((A))
103 //#define AUDIO_CONV16(A) ((A))
105 /* ------------------------------------------------------------------ */
108 #define INTERNAL_TIMER /* use internal timer */
111 /* -------------------- speed up optimize switch -------------------- */
112 /* ---------- Enable ---------- */
113 #define TL_SAVE_MEM /* save some memories for total level */
114 /* ---------- Disable ---------- */
116 #define SEG_SUPPORT /* OPN SSG type envelope support */
117 #define LFO_SUPPORT /* LFO support */
119 /* -------------------- preliminary define section --------------------- */
120 /* attack/decay rate time rate */
121 #define OPM_ARRATE 399128
122 #define OPM_DRRATE 5514396
123 /* It is not checked , because I haven't YM2203 rate */
124 #define OPN_ARRATE OPM_ARRATE
125 #define OPN_DRRATE OPM_DRRATE
127 #define FREQ_BITS 24 /* frequency turn */
129 /* counter bits = 21 , octerve 7 */
130 #define FREQ_RATE (1<<(FREQ_BITS-21))
131 #define TL_BITS (FREQ_BITS+2)
133 /* final output shift , limit minimum and maximum */
134 #define OPN_OUTSB (TL_BITS+2-16) /* OPN output final shift 16bit */
135 #define OPN_MAXOUT (0x7fff<<OPN_OUTSB)
136 #define OPN_MINOUT (-0x8000<<OPN_OUTSB)
138 #define OPM_OUTSB (TL_BITS+2-16) /* OPM output final shift 16bit */
139 #define OPM_MAXOUT (0x7fff<<OPM_OUTSB)
140 #define OPM_MINOUT (-0x8000<<OPM_OUTSB)
142 #define OPNB_OUTSB (TL_BITS+2-16) /* OPN output final shift 16bit */
143 #define OPNB_MAXOUT (0x7fff<<OPNB_OUTSB)
144 #define OPNB_MINOUT (-0x8000<<OPNB_OUTSB)
146 /* -------------------- quality selection --------------------- */
148 /* sinwave entries */
149 /* used static memory = SIN_ENT * 4 (byte) */
152 /* output level entries (envelope,sinwave) */
153 /* envelope counter lower bits */
155 /* envelope output entries */
157 /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
158 /* used static memory = EG_ENT*4 (byte) */
161 #define EG_OFF ((3*EG_ENT)<<ENV_BITS) /* OFF */
162 #define EG_UED EG_OFF
163 #define EG_UST ((2*EG_ENT)<<ENV_BITS) /* UPSISE START */
164 #define EG_DED EG_UST
166 #define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */
167 #define EG_DED EG_OFF
169 #define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */
170 #define EG_AED EG_DST
171 #define EG_AST 0 /* ATTACK START */
173 #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */
175 /* LFO table entries */
178 /* -------------------- local defines , macros --------------------- */
179 /* number of maximum envelope counter */
180 /* #define ENV_OFF ((EG_ENT<<ENV_BITS)-1) */
182 /* register number to channel number , slot offset */
183 #define OPN_CHAN(N) (N&3)
184 #define OPN_SLOT(N) ((N>>2)&3)
185 #define OPM_CHAN(N) (N&7)
186 #define OPM_SLOT(N) ((N>>3)&3)
194 #define ENV_MOD_OFF 0x00
195 #define ENV_MOD_RR 0x01
196 #define ENV_MOD_SR 0x02
197 #define ENV_MOD_DR 0x03
198 #define ENV_MOD_AR 0x04
199 #define ENV_SSG_SR 0x05
200 #define ENV_SSG_DR 0x06
201 #define ENV_SSG_AR 0x07
203 /* bit0 = right enable , bit1 = left enable (FOR YM2612) */
208 /* bit0 = left enable , bit1 = right enable */
214 /* YM2608 Rhythm Number */
223 #define FM_TIMER_SINGLE (0)
224 #define FM_TIMER_INTERVAL (1)
226 /* ---------- OPN / OPM one channel ---------- */
227 typedef struct fm_slot
{
228 int *DT
; /* detune :DT_TABLE[DT] */
229 int DT2
; /* multiple,Detune2:(DT2<<4)|ML for OPM*/
230 int TL
; /* total level :TL << 8 */
231 signed int TLL
; /* adjusted now TL */
232 unsigned char KSR
; /* key scale rate :3-KSR */
233 int *AR
; /* attack rate :&AR_TABLE[AR<<1] */
234 int *DR
; /* decay rate :&DR_TALBE[DR<<1] */
235 int *SR
; /* sustin rate :&DR_TABLE[SR<<1] */
236 int SL
; /* sustin level :SL_TALBE[SL] */
237 int *RR
; /* release rate :&DR_TABLE[RR<<2+2] */
238 unsigned char SEG
; /* SSG EG type :SSGEG */
239 unsigned char ksr
; /* key scale rate :kcode>>(3-KSR) */
240 unsigned int mul
; /* multiple :ML_TABLE[ML] */
241 unsigned int Cnt
; /* frequency count : */
242 unsigned int Incr
; /* frequency step : */
243 /* envelope generator state */
244 unsigned char evm
; /* envelope phase */
245 signed int evc
; /* envelope counter */
246 signed int eve
; /* envelope counter end point */
247 signed int evs
; /* envelope counter step */
248 signed int evsa
; /* envelope step for AR */
249 signed int evsd
; /* envelope step for DR */
250 signed int evss
; /* envelope step for SR */
251 signed int evsr
; /* envelope step for RR */
258 typedef struct fm_chan
{
260 unsigned char PAN
; /* PAN NONE,LEFT,RIGHT or CENTER */
261 unsigned char ALGO
; /* algorythm */
262 unsigned char FB
; /* feed back :&FB_TABLE[FB<<8] */
263 int op1_out
; /* op1 output foe beedback */
264 /* algorythm state */
265 int *connect1
; /* operator 1 connection pointer */
266 int *connect2
; /* operator 2 connection pointer */
267 int *connect3
; /* operator 3 connection pointer */
268 int *connect4
; /* operator 4 connection pointer */
269 /* phase generator state */
270 unsigned int fc
; /* fnum,blk :calcrated */
271 unsigned char fn_h
; /* freq latch : */
272 unsigned char kcode
; /* key code : */
275 /* OPN/OPM common state */
276 typedef struct fm_state
{
277 unsigned char index
; /* chip index (number of chip) */
278 int clock
; /* master clock (Hz) */
279 int rate
; /* sampling rate (Hz) */
280 int freqbase
; /* frequency base */
281 double TimerBase
; /* Timer base time */
282 unsigned char address
; /* address register */
283 unsigned char irq
; /* interrupt level */
284 unsigned char irqmask
; /* irq mask */
285 unsigned char status
; /* status flag */
286 unsigned int mode
; /* mode CSM / 3SLOT */
287 int TA
; /* timer a */
288 int TAC
; /* timer a counter */
289 unsigned char TB
; /* timer b */
290 int TBC
; /* timer b counter */
291 /* speedup customize */
293 signed int DT_TABLE
[8][32]; /* detune tables */
294 signed int AR_TABLE
[94]; /* atttack rate tables */
295 signed int DR_TABLE
[94]; /* decay rate tables */
298 unsigned int LFOIncr
;
299 /* Extention Timer and IRQ handler */
300 FM_TIMERHANDLER Timer_Handler
;
301 FM_IRQHANDLER IRQ_Handler
;
302 /* timer model single / interval */
303 unsigned char timermodel
;
306 /* OPN 3slot struct */
307 typedef struct opn_3slot
{
308 unsigned int fc
[3]; /* fnum3,blk3 :calcrated */
309 unsigned char fn_h
[3]; /* freq3 latch */
310 unsigned char kcode
[3]; /* key code : */
313 /* adpcm type A and type B struct */
314 typedef struct adpcm_state
{
315 unsigned char flag
; /* port state */
316 unsigned char flagMask
; /* arrived */
317 unsigned char now_data
;
318 unsigned int now_addr
;
319 unsigned int now_step
;
326 int *pan
; /* &outd[OPN_xxxx] */
327 int /*adpcmm,*/ adpcmx
, adpcmd
;
328 int adpcml
; /* hiro-shi!! */
330 /* leveling and re-sampling state for DELTA-T */
331 int volume_w_step
; /* volume with step rate */
332 int next_leveling
; /* leveling value */
333 int sample_step
; /* step of re-sampling */
336 /* OPN/A/B common state */
337 typedef struct opn_f
{
338 unsigned char type
; /* chip type */
339 FM_ST ST
; /* general state */
340 FM_3SLOT SL3
; /* 3 slot mode state */
341 FM_CH
*P_CH
; /* pointer of CH */
342 unsigned int FN_TABLE
[2048]; /* fnumber -> increment counter */
345 /* here's the virtual YM2203(OPN) (Used by YM2608 / YM2612) */
346 typedef struct ym2203_f
{
347 FM_OPN OPN
; /* OPN state */
348 /* FMSAMPLE *Buf;*/ /* sound buffer */
349 FM_CH CH
[3]; /* channel state */
352 /* here's the virtual YM2610 */
353 typedef struct ym2610_f
{
354 FM_OPN OPN
; /* OPN state */
355 /* FMSAMPLE *Buf[YM2610_NUMBUF];*/ /* sound buffer */
356 FM_CH CH
[6]; /* channel state */
357 int address1
; /* address register1 */
358 /**** ADPCM control ****/
360 unsigned int pcm_size
[2];
362 ADPCM_CH adpcm
[7]; /* normal ADPCM & deltaT ADPCM */
363 unsigned int adpcmreg
[2][0x30];
364 int port0state
, port0control
, port0shift
;
365 int port1state
, port1control
, port1shift
;
366 unsigned char adpcm_arrivedEndAddress
,adpcm_statusmask
;
369 /* here's the virtual YM2608 */
370 typedef YM2610 YM2608
;
372 /* here's the virtual YM2612 */
373 typedef struct ym2612_f
{
374 FM_OPN OPN
; /* OPN state */
375 /* FMSAMPLE *Buf[YM2612_NUMBUF];*/ /* sound buffer */
376 FM_CH CH
[6]; /* channel state */
377 int address1
; /* address register1 */
378 /* dac output (YM2612) */
383 /* here's the virtual YM2151(OPM) */
384 typedef struct ym2151_f
{
385 /* FMSAMPLE *Buf[YM2151_NUMBUF];*//* sound buffers */
386 FM_ST ST
; /* general state */
387 FM_CH CH
[8]; /* channel state */
388 unsigned char NReg
; /* noise enable,freq */
389 unsigned char pmd
; /* LFO pmd level */
390 unsigned char amd
; /* LFO amd level */
391 unsigned char ctw
; /* CT0,1 and waveform */
392 unsigned int KC_TABLE
[8*12*64+950];/* keycode,keyfunction -> count */
393 void (*PortWrite
)(int offset
,int data
);/* callback when write CT0/CT1 */
396 /* -------------------- tables --------------------- */
398 /* key scale level */
399 /* !!!!! preliminary !!!!! */
401 #define DV (1/EG_STEP)
402 static const unsigned char KSL
[32]=
405 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
407 0.000/DV
, 0.000/DV
, 0.000/DV
, 0.000/DV
, /* OCT 0 */
408 0.000/DV
, 0.000/DV
, 0.000/DV
, 1.875/DV
, /* OCT 1 */
409 0.000/DV
, 0.000/DV
, 3.000/DV
, 4.875/DV
, /* OCT 2 */
410 0.000/DV
, 3.000/DV
, 6.000/DV
, 7.875/DV
, /* OCT 3 */
411 0.000/DV
, 6.000/DV
, 9.000/DV
,10.875/DV
, /* OCT 4 */
412 0.000/DV
, 9.000/DV
,12.000/DV
,13.875/DV
, /* OCT 5 */
413 0.000/DV
,12.000/DV
,15.000/DV
,16.875/DV
, /* OCT 6 */
414 0.000/DV
,15.000/DV
,18.000/DV
,19.875/DV
/* OCT 7 */
419 /* OPN key frequency number -> key code follow table */
420 /* fnum higher 4bit -> keycode lower 2bit */
421 static const char OPN_FKTABLE
[16]={0,0,0,0,0,0,0,1,2,3,3,3,3,3,3,3};
423 static const int KC_TO_SEMITONE
[16]={
424 /*translate note code KC into more usable number of semitone*/
425 0*64, 1*64, 2*64, 3*64,
426 3*64, 4*64, 5*64, 6*64,
427 6*64, 7*64, 8*64, 9*64,
428 9*64,10*64,11*64,12*64
431 static const int DT2_TABLE
[4]={ /* 4 DT2 values */
433 * DT2 defines offset in cents from base note
435 * The table below defines offset in deltas table...
436 * User's Manual page 22
437 * Values below were calculated using formula: value = orig.val * 1.5625
439 * DT2=0 DT2=1 DT2=2 DT2=3
445 /* sustain lebel table (3db per step) */
446 /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
447 #define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
448 static const int SL_TABLE
[16]={
449 SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
450 SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
455 #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
457 #define TL_MAX (EG_ENT*4) /* tl + ksr + envelope + sinwave */
460 /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */
461 /* TL_TABLE[ 0 to TL_MAX ] : plus section */
462 /* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
463 static int *TL_TABLE
;
465 /* pointers to TL_TABLE with sinwave output offset */
466 static signed int *SIN_TABLE
[SIN_ENT
];
468 /* envelope output curve table */
470 /* attack + decay + SSG upside + OFF */
471 static int ENV_CURVE
[3*EG_ENT
+1];
473 /* attack + decay + OFF */
474 static int ENV_CURVE
[2*EG_ENT
+1];
476 /* envelope counter conversion table when change Decay to Attack phase */
477 static int DRAR_TABLE
[EG_ENT
];
479 #define OPM_DTTABLE OPN_DTTABLE
480 static char OPN_DTTABLE
[4 * 32]={
481 /* this table is YM2151 and YM2612 data */
483 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
484 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
486 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
487 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 8, 8, 8, 8,
489 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
490 5, 6, 6, 7, 8, 8, 9,10,11,12,13,14,16,16,16,16,
492 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
493 8 , 8, 9,10,11,12,13,14,16,17,19,20,22,22,22,22
498 static const int MUL_TABLE
[4*16]= {
499 /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
500 0.50*ML
, 1.00*ML
, 2.00*ML
, 3.00*ML
, 4.00*ML
, 5.00*ML
, 6.00*ML
, 7.00*ML
,
501 8.00*ML
, 9.00*ML
,10.00*ML
,11.00*ML
,12.00*ML
,13.00*ML
,14.00*ML
,15.00*ML
,
503 0.71*ML
, 1.41*ML
, 2.82*ML
, 4.24*ML
, 5.65*ML
, 7.07*ML
, 8.46*ML
, 9.89*ML
,
504 11.30*ML
,12.72*ML
,14.10*ML
,15.55*ML
,16.96*ML
,18.37*ML
,19.78*ML
,21.20*ML
,
505 /* DT2=2 *SQL(2.5) */
506 0.78*ML
, 1.57*ML
, 3.14*ML
, 4.71*ML
, 6.28*ML
, 7.85*ML
, 9.42*ML
,10.99*ML
,
507 12.56*ML
,14.13*ML
,15.70*ML
,17.27*ML
,18.84*ML
,20.41*ML
,21.98*ML
,23.55*ML
,
509 0.87*ML
, 1.73*ML
, 3.46*ML
, 5.19*ML
, 6.92*ML
, 8.65*ML
,10.38*ML
,12.11*ML
,
510 13.84*ML
,15.57*ML
,17.30*ML
,19.03*ML
,20.76*ML
,22.49*ML
,24.22*ML
,25.95*ML
515 /* LFO frequency timer table */
516 static int OPM_LFO_TABLE
[256];
519 /* dummy attack / decay rate ( when rate == 0 ) */
520 static int RATE_0
[32]=
521 {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};
523 /* -------------------- state --------------------- */
526 #define TYPE_SSG 0x01 /* SSG support */
527 #define TYPE_OPN 0x02 /* OPN device */
528 #define TYPE_LFOPAN 0x04 /* OPN type LFO and PAN */
529 #define TYPE_6CH 0x08 /* FM 6CH / 3CH */
530 #define TYPE_DAC 0x10 /* YM2612's DAC device */
531 #define TYPE_ADPCM 0x20 /* ADPCM device */
533 #define TYPE_YM2203 (TYPE_SSG)
534 #define TYPE_YM2608 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
535 #define TYPE_YM2610 (TYPE_SSG |TYPE_LFOPAN |TYPE_6CH |TYPE_ADPCM)
536 #define TYPE_YM2612 (TYPE_6CH |TYPE_LFOPAN |TYPE_DAC)
538 static int FMNumChips
; /* total # of FM emulated */
541 static void *cur_chip
= 0; /* current chip point */
543 /* currenct chip state */
545 static FMSAMPLE
*bufL
,*bufR
;
546 static FM_CH
*cch
[8];
547 static signed int outd
[4];
549 /* operator connection work */
550 static int feedback2
; /* connect for operator 2 */
551 static int feedback3
; /* connect for operator 3 */
552 static int feedback4
; /* connect for operator 4 */
554 /* log output level */
555 #define LOG_ERR 3 /* ERROR */
556 #define LOG_WAR 2 /* WARNING */
557 #define LOG_INF 1 /* INFORMATION */
559 #define LOG_LEVEL LOG_INF
562 static void Log(int level
,char *format
,...)
567 if( level
< LOG_LEVEL
) return;
568 va_start(argptr
,format
);
570 //if (errorlog) vfprintf( errorlog, format , argptr);
574 /* --------------- Customize External interface port (SSG,Timer,etc) ---------------*/
577 /* --------------------- subroutines --------------------- */
579 INLINE
int Limit( int val
, int max
, int min
) {
582 else if ( val
< min
)
588 /* status set and IRQ handling */
589 INLINE
void FM_STATUS_SET(FM_ST
*ST
,int flag
)
591 /* set status flag */
593 if ( !(ST
->irq
) && (ST
->status
& ST
->irqmask
) )
596 /* callback user interrupt handler (IRQ is OFF to ON) */
597 if(ST
->IRQ_Handler
) (ST
->IRQ_Handler
)(ST
->index
,1);
601 /* status reset and IRQ handling */
602 INLINE
void FM_STATUS_RESET(FM_ST
*ST
,int flag
)
604 /* reset status flag */
606 if ( (ST
->irq
) && !(ST
->status
& ST
->irqmask
) )
609 /* callback user interrupt handler (IRQ is ON to OFF) */
610 if(ST
->IRQ_Handler
) (ST
->IRQ_Handler
)(ST
->index
,0);
615 INLINE
void FM_IRQMASK_SET(FM_ST
*ST
,int flag
)
618 /* IRQ handling check */
620 FM_STATUS_RESET(ST
,0);
623 /* ----- key on ----- */
624 INLINE
void FM_KEYON(FM_CH
*CH
, int s
)
626 FM_SLOT
*SLOT
= &CH
->SLOT
[s
];
627 if( SLOT
->evm
<= ENV_MOD_RR
)
629 /* set envelope counter from envleope output */
631 /* sin wave restart */
633 if( s
== SLOT1
) CH
->op1_out
= 0;
636 if( SLOT
->SEG
&8 ) ENV_SSG_AR
;
639 SLOT
->evm
= ENV_MOD_AR
;
640 SLOT
->evs
= SLOT
->evsa
;
642 /* convert decay count to attack count */
643 /* --- This caused the problem by credit sound of paper boy. --- */
644 SLOT
->evc
= EG_AST
+ DRAR_TABLE
[ENV_CURVE
[SLOT
->evc
>>ENV_BITS
]];/* + SLOT->evs;*/
646 /* reset attack counter */
652 /* ----- key off ----- */
653 INLINE
void FM_KEYOFF(FM_CH
*CH
, int s
)
655 FM_SLOT
*SLOT
= &CH
->SLOT
[s
];
656 if( SLOT
->evm
> ENV_MOD_RR
)
658 /* set envelope counter from envleope output */
659 SLOT
->evm
= ENV_MOD_RR
;
660 if( !(SLOT
->evc
&EG_DST
) )
661 SLOT
->evc
= (ENV_CURVE
[SLOT
->evc
>>ENV_BITS
]<<ENV_BITS
) + EG_DST
;
663 SLOT
->evs
= SLOT
->evsr
;
667 /* ---------- calcrate Envelope Generator & Phase Generator ---------- */
668 /* return : envelope output */
669 INLINE
signed int FM_CALC_SLOT( FM_SLOT
*SLOT
)
671 /* calcrate phage generator */
672 SLOT
->Cnt
+= SLOT
->Incr
;
673 /* calcrate envelope generator */
674 if( (SLOT
->evc
+=SLOT
->evs
) >= SLOT
->eve
)
677 case ENV_MOD_AR
: /* ATTACK -> DECAY1 */
679 SLOT
->evm
= ENV_MOD_DR
;
681 SLOT
->eve
= SLOT
->SL
;
682 SLOT
->evs
= SLOT
->evsd
;
684 case ENV_MOD_DR
: /* DECAY -> SUSTAIN */
685 SLOT
->evm
= ENV_MOD_SR
;
686 SLOT
->evc
= SLOT
->SL
;
688 SLOT
->evs
= SLOT
->evss
;
690 case ENV_MOD_RR
: /* RR -> OFF & STOP */
691 SLOT
->evm
= ENV_MOD_OFF
;
692 case ENV_MOD_SR
: /* SR -> OFF & STOP */
694 SLOT
->eve
= EG_OFF
+1;
698 case ENV_SSG_AR
: /* SSG ATTACK */
699 if( SLOT
->SEG
&4){ /* start direction */
700 /* next SSG-SR (upside start ) */
701 SLOT
->evm
= ENV_SSG_SR
;
702 SLOT
->evc
= SLOT
->SL
+ (EG_UST
- EG_DST
);
704 SLOT
->evs
= SLOT
->evss
;
706 /* next SSG-DR (downside start ) */
707 SLOT
->evm
= ENV_SSG_DR
;
710 SLOT
->evs
= SLOT
->evsd
;
713 case ENV_SSG_DR
: /* SEG down side */
716 SLOT
->evm
= ENV_SSG_SR
;
717 SLOT
->evc
= SLOT
->SL
+ (EG_UST
- EG_DST
);
719 SLOT
->evs
= SLOT
->evss
;
725 if( SLOT
->SEG
&1) SLOT
->evs
= 0;
727 case ENV_SSG_SR
: /* upside */
730 SLOT
->evm
= ENV_SSG_DR
;
733 SLOT
->evs
= SLOT
->evsd
;
736 SLOT
->evc
= SLOT
->SL
+ (EG_UST
- EG_DST
);
739 if( SLOT
->SEG
&1) SLOT
->evs
= 0;
744 /* calcrate envelope */
745 #if 0 /* ifdef TL_SAVE_MEM */
746 signed int env_out
= SLOT
->TLL
+ENV_CURVE
[SLOT
->evc
>>ENV_BITS
]; /* LFO_out[SLOT->AMS] */
747 if(env_out
>= (EG_ENT
-1) ) return EG_ENT
-1;
750 return SLOT
->TLL
+ENV_CURVE
[SLOT
->evc
>>ENV_BITS
]; /* LFO_out[SLOT->AMS] */
754 /* set algorythm connection */
755 static void set_algorythm( FM_CH
*CH
)
757 signed int *carrier
= &outd
[CH
->PAN
];
759 /* setup connect algorythm */
762 /* PG---S1---S2---S3---S4---OUT */
763 CH
->connect1
= &feedback2
;
764 CH
->connect2
= &feedback3
;
765 CH
->connect3
= &feedback4
;
768 /* PG---S1-+-S3---S4---OUT */
770 CH
->connect1
= &feedback3
;
771 CH
->connect2
= &feedback3
;
772 CH
->connect3
= &feedback4
;
775 /* PG---S1------+-S4---OUT */
777 CH
->connect1
= &feedback4
;
778 CH
->connect2
= &feedback3
;
779 CH
->connect3
= &feedback4
;
782 /* PG---S1---S2-+-S4---OUT */
784 CH
->connect1
= &feedback2
;
785 CH
->connect2
= &feedback4
;
786 CH
->connect3
= &feedback4
;
789 /* PG---S1---S2-+--OUT */
791 CH
->connect1
= &feedback2
;
792 CH
->connect2
= carrier
;
793 CH
->connect3
= &feedback4
;
797 /* PG---S1-+-S3-+-OUT */
799 CH
->connect1
= 0; /* special mark */
800 CH
->connect2
= carrier
;
801 CH
->connect3
= carrier
;
805 /* PG--------S3-+-OUT */
807 CH
->connect1
= &feedback2
;
808 CH
->connect2
= carrier
;
809 CH
->connect3
= carrier
;
816 CH
->connect1
= carrier
;
817 CH
->connect2
= carrier
;
818 CH
->connect3
= carrier
;
820 CH
->connect4
= carrier
;
823 /* set detune & multiple */
824 INLINE
void set_det_mul(FM_ST
*ST
,FM_CH
*CH
,FM_SLOT
*SLOT
,int v
)
826 SLOT
->mul
= MUL_TABLE
[v
&0x0f];
827 SLOT
->DT
= ST
->DT_TABLE
[(v
>>4)&7];
828 CH
->SLOT
[SLOT1
].Incr
=-1;
831 /* set total level */
832 INLINE
void set_tl(FM_CH
*CH
,FM_SLOT
*SLOT
, int v
,int csmflag
)
835 v
= (v
<<7)|v
; /* 7bit -> 14bit */
836 SLOT
->TL
= (v
*EG_ENT
)>>14;
838 { /* not CSM latch total level */
839 SLOT
->TLL
= SLOT
->TL
+ KSL
[CH
->kcode
];
843 /* set attack rate & key scale */
844 INLINE
void set_ar_ksr(FM_CH
*CH
,FM_SLOT
*SLOT
,int v
,signed int *ar_table
)
846 SLOT
->KSR
= 3-(v
>>6);
847 SLOT
->AR
= (v
&=0x1f) ? &ar_table
[v
<<1] : RATE_0
;
848 SLOT
->evsa
= SLOT
->AR
[SLOT
->ksr
];
849 if( SLOT
->evm
== ENV_MOD_AR
) SLOT
->evs
= SLOT
->evsa
;
850 CH
->SLOT
[SLOT1
].Incr
=-1;
853 INLINE
void set_dr(FM_SLOT
*SLOT
,int v
,signed int *dr_table
)
855 SLOT
->DR
= (v
&=0x1f) ? &dr_table
[v
<<1] : RATE_0
;
856 SLOT
->evsd
= SLOT
->DR
[SLOT
->ksr
];
857 if( SLOT
->evm
== ENV_MOD_DR
) SLOT
->evs
= SLOT
->evsd
;
859 /* set sustain rate */
860 INLINE
void set_sr(FM_SLOT
*SLOT
,int v
,signed int *dr_table
)
862 SLOT
->SR
= (v
&=0x1f) ? &dr_table
[v
<<1] : RATE_0
;
863 SLOT
->evss
= SLOT
->SR
[SLOT
->ksr
];
864 if( SLOT
->evm
== ENV_MOD_SR
) SLOT
->evs
= SLOT
->evss
;
866 /* set release rate */
867 INLINE
void set_sl_rr(FM_SLOT
*SLOT
,int v
,signed int *dr_table
)
869 SLOT
->SL
= SL_TABLE
[(v
>>4)];
870 SLOT
->RR
= &dr_table
[((v
&0x0f)<<2)|2];
871 SLOT
->evsr
= SLOT
->RR
[SLOT
->ksr
];
872 if( SLOT
->evm
== ENV_MOD_RR
) SLOT
->evs
= SLOT
->evsr
;
875 /* operator output calcrator */
876 #define OP_OUT(slot,env,con) SIN_TABLE[((slot.Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
877 /* ---------- calcrate one of channel ---------- */
878 INLINE
void FM_CALC_CH( FM_CH
*CH
)
883 feedback2
= feedback3
= feedback4
= 0;
886 env_out
=FM_CALC_SLOT(&CH
->SLOT
[SLOT1
]);
887 if( env_out
< EG_ENT
-1 )
890 /* with self feed back */
891 op_out
= CH
->op1_out
;
892 CH
->op1_out
= OP_OUT(CH
->SLOT
[SLOT1
],env_out
,(CH
->op1_out
>>CH
->FB
) /* +LFOOut[SLOT->AMS]*/ );
893 op_out
= (op_out
+ CH
->op1_out
)/2;
895 /* without self feed back */
896 op_out
= OP_OUT(CH
->SLOT
[SLOT1
],env_out
,0 /* +LFOOut[SLOT->AMS]*/ );
902 feedback2
= feedback3
= feedback4
= op_out
;
904 /* other algorythm */
905 *CH
->connect1
+= op_out
;
909 env_out
=FM_CALC_SLOT(&CH
->SLOT
[SLOT2
]);
910 if( env_out
< EG_ENT
-1 )
911 *CH
->connect2
+= OP_OUT(CH
->SLOT
[SLOT2
],env_out
, feedback2
/* +LFOOut[SLOT->AMS]*/ );
913 env_out
=FM_CALC_SLOT(&CH
->SLOT
[SLOT3
]);
914 if( env_out
< EG_ENT
-1 )
915 *CH
->connect3
+= OP_OUT(CH
->SLOT
[SLOT3
],env_out
, feedback3
/* +LFOOut[SLOT->AMS]*/ );
917 env_out
=FM_CALC_SLOT(&CH
->SLOT
[SLOT4
]);
918 if( env_out
< EG_ENT
-1 )
919 *CH
->connect4
+= OP_OUT(CH
->SLOT
[SLOT4
],env_out
, feedback4
/* +LFOOut[SLOT->AMS]*/ );
921 /* ---------- frequency counter for operater update ---------- */
922 INLINE
void CALC_FCSLOT(FM_SLOT
*SLOT
, int fc
, int kc
)
926 /* frequency step counter */
927 SLOT
->Incr
= (fc
+SLOT
->DT
[kc
])*SLOT
->mul
;
928 ksr
= kc
>> SLOT
->KSR
;
929 if( SLOT
->ksr
!= ksr
)
932 /* attack , decay rate recalcration */
933 SLOT
->evsa
= SLOT
->AR
[ksr
];
934 SLOT
->evsd
= SLOT
->DR
[ksr
];
935 SLOT
->evss
= SLOT
->SR
[ksr
];
936 SLOT
->evsr
= SLOT
->RR
[ksr
];
938 SLOT
->TLL
= SLOT
->TL
+ KSL
[kc
];
941 /* ---------- frequency counter ---------- */
942 INLINE
void CALC_FCOUNT(FM_CH
*CH
)
944 if( CH
->SLOT
[SLOT1
].Incr
==-1){
947 CALC_FCSLOT(&CH
->SLOT
[SLOT1
] , fc
, kc
);
948 CALC_FCSLOT(&CH
->SLOT
[SLOT2
] , fc
, kc
);
949 CALC_FCSLOT(&CH
->SLOT
[SLOT3
] , fc
, kc
);
950 CALC_FCSLOT(&CH
->SLOT
[SLOT4
] , fc
, kc
);
954 /* ---------- frequency counter ---------- */
955 INLINE
void OPM_CALC_FCOUNT(YM2151
*OPM
, FM_CH
*CH
)
957 if( CH
->SLOT
[SLOT1
].Incr
==-1)
961 CALC_FCSLOT(&CH
->SLOT
[SLOT1
] , OPM
->KC_TABLE
[fc
+ CH
->SLOT
[SLOT1
].DT2
] , kc
);
962 CALC_FCSLOT(&CH
->SLOT
[SLOT2
] , OPM
->KC_TABLE
[fc
+ CH
->SLOT
[SLOT2
].DT2
] , kc
);
963 CALC_FCSLOT(&CH
->SLOT
[SLOT3
] , OPM
->KC_TABLE
[fc
+ CH
->SLOT
[SLOT3
].DT2
] , kc
);
964 CALC_FCSLOT(&CH
->SLOT
[SLOT4
] , OPM
->KC_TABLE
[fc
+ CH
->SLOT
[SLOT4
].DT2
] , kc
);
967 /* ----------- initialize time tabls ----------- */
968 static void init_timetables( FM_ST
*ST
, char *DTTABLE
, int ARRATE
, int DRRATE
)
973 /* make detune table */
974 for (d
= 0;d
<= 3;d
++){
975 for (i
= 0;i
<= 31;i
++){
976 rate
= (double)DTTABLE
[d
*32 + i
] * ST
->freqbase
/ 4096 * FREQ_RATE
;
977 ST
->DT_TABLE
[d
][i
] = rate
;
978 ST
->DT_TABLE
[d
+4][i
] = -rate
;
981 /* make attack rate & decay rate tables */
982 for (i
= 0;i
< 4;i
++) ST
->AR_TABLE
[i
] = ST
->DR_TABLE
[i
] = 0;
983 for (i
= 4;i
< 64;i
++){
984 rate
= (double)ST
->freqbase
/ 4096.0; /* frequency rate */
985 if( i
< 60 ) rate
*= 1.0+(i
&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
986 rate
*= 1<<((i
>>2)-1); /* b2-5 : shift bit */
987 rate
*= (double)(EG_ENT
<<ENV_BITS
);
988 ST
->AR_TABLE
[i
] = rate
/ ARRATE
;
989 ST
->DR_TABLE
[i
] = rate
/ DRRATE
;
991 ST
->AR_TABLE
[62] = EG_AED
-1;
992 ST
->AR_TABLE
[63] = EG_AED
-1;
993 for (i
= 64;i
< 94 ;i
++){ /* make for overflow area */
994 ST
->AR_TABLE
[i
] = ST
->AR_TABLE
[63];
995 ST
->DR_TABLE
[i
] = ST
->DR_TABLE
[63];
999 for (i
= 0;i
< 64 ;i
++){ /* make for overflow area */
1000 Log(LOG_WAR
,"rate %2d , ar %f ms , dr %f ms \n",i
,
1001 ((double)(EG_ENT
<<ENV_BITS
) / ST
->AR_TABLE
[i
]) * (1000.0 / ST
->rate
),
1002 ((double)(EG_ENT
<<ENV_BITS
) / ST
->DR_TABLE
[i
]) * (1000.0 / ST
->rate
) );
1007 /* ---------- reset one of channel ---------- */
1008 static void reset_channel( FM_ST
*ST
, FM_CH
*CH
, int chan
)
1012 ST
->mode
= 0; /* normal mode */
1013 FM_STATUS_RESET(ST
,0xff);
1019 for( c
= 0 ; c
< chan
; c
++ )
1022 CH
[c
].PAN
= OPN_CENTER
; /* or OPM_CENTER */
1023 for(s
= 0 ; s
< 4 ; s
++ )
1025 CH
[c
].SLOT
[s
].SEG
= 0;
1026 CH
[c
].SLOT
[s
].evm
= ENV_MOD_OFF
;
1027 CH
[c
].SLOT
[s
].evc
= EG_OFF
;
1028 CH
[c
].SLOT
[s
].eve
= EG_OFF
+1;
1029 CH
[c
].SLOT
[s
].evs
= 0;
1034 /* ---------- generic table initialize ---------- */
1035 static int FMInitTable( void )
1042 /* allocate total level table */
1043 TL_TABLE
= malloc(TL_MAX
*2*sizeof(int));
1044 if( TL_TABLE
== 0 ) return 0;
1045 /* make total level table */
1046 for (t
= 0;t
< EG_ENT
-1 ;t
++){
1047 rate
= ((1<<TL_BITS
)-1)/pow(10,EG_STEP
*t
/20); /* dB -> voltage */
1048 TL_TABLE
[ t
] = (int)rate
;
1049 TL_TABLE
[TL_MAX
+t
] = -TL_TABLE
[t
];
1050 /* Log(LOG_INF,"TotalLevel(%3d) = %x\n",t,TL_TABLE[t]);*/
1052 /* fill volume off area */
1053 for ( t
= EG_ENT
-1; t
< TL_MAX
;t
++){
1054 TL_TABLE
[t
] = TL_TABLE
[TL_MAX
+t
] = 0;
1057 /* make sinwave table (total level offet) */
1058 /* degree 0 = degree 180 = off */
1059 SIN_TABLE
[0] = SIN_TABLE
[SIN_ENT
/2] = &TL_TABLE
[EG_ENT
-1];
1060 for (s
= 1;s
<= SIN_ENT
/4;s
++){
1061 pom
= sin(2*PI
*s
/SIN_ENT
); /* sin */
1062 pom
= 20*log10(1/pom
); /* decibel */
1063 j
= pom
/ EG_STEP
; /* TL_TABLE steps */
1065 /* degree 0 - 90 , degree 180 - 90 : plus section */
1066 SIN_TABLE
[ s
] = SIN_TABLE
[SIN_ENT
/2-s
] = &TL_TABLE
[j
];
1067 /* degree 180 - 270 , degree 360 - 270 : minus section */
1068 SIN_TABLE
[SIN_ENT
/2+s
] = SIN_TABLE
[SIN_ENT
-s
] = &TL_TABLE
[TL_MAX
+j
];
1069 /* Log(LOG_INF,"sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP);*/
1071 /* envelope counter -> envelope output table */
1072 for (i
=0; i
<EG_ENT
; i
++)
1075 /* !!!!! preliminary !!!!! */
1076 pom
= pow( ((double)(EG_ENT
-1-i
)/EG_ENT
) , 8 ) * EG_ENT
;
1077 /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
1078 ENV_CURVE
[i
] = (int)pom
;
1079 /* DECAY ,RELEASE curve */
1080 ENV_CURVE
[(EG_DST
>>ENV_BITS
)+i
]= i
;
1082 /* DECAY UPSIDE (SSG ENV) */
1083 ENV_CURVE
[(EG_UST
>>ENV_BITS
)+i
]= EG_ENT
-1-i
;
1087 ENV_CURVE
[EG_OFF
>>ENV_BITS
]= EG_ENT
-1;
1089 /* decay to reattack envelope converttable */
1091 for (i
=0; i
<EG_ENT
; i
++)
1093 while( j
&& (ENV_CURVE
[j
] < i
) ) j
--;
1094 DRAR_TABLE
[i
] = j
<<ENV_BITS
;
1095 /* Log(LOG_INF,"DR %06X = %06X,AR=%06X\n",i,DRAR_TABLE[i],ENV_CURVE[DRAR_TABLE[i]>>ENV_BITS] ); */
1101 static void FMCloseTable( void )
1103 if( TL_TABLE
) free( TL_TABLE
);
1107 /* OPN/OPM Mode Register Write */
1108 INLINE
void FMSetMode( FM_ST
*ST
,int n
,int v
)
1111 /* b6 = 3 slot mode */
1114 /* b3 = timer enable b */
1115 /* b2 = timer enable a */
1120 /* reset Timer b flag */
1122 FM_STATUS_RESET(ST
,0x02);
1123 /* reset Timer a flag */
1125 FM_STATUS_RESET(ST
,0x01);
1131 ST
->TBC
= ( 256-ST
->TB
)<<4;
1132 /* External timer handler */
1133 // if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,(double)ST->TBC,ST->TimerBase);
1135 }else if (ST
->timermodel
== FM_TIMER_INTERVAL
)
1136 { /* stop interbval timer */
1140 // if (ST->Timer_Handler) (ST->Timer_Handler)(n,1,0,ST->TimerBase);
1148 ST
->TAC
= (1024-ST
->TA
);
1149 /* External timer handler */
1150 // if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,(double)ST->TAC,ST->TimerBase);
1152 }else if (ST
->timermodel
== FM_TIMER_INTERVAL
)
1153 { /* stop interbval timer */
1157 // if (ST->Timer_Handler) (ST->Timer_Handler)(n,0,0,ST->TimerBase);
1162 /* Timer A Overflow */
1163 INLINE
void TimerAOver(FM_ST
*ST
)
1165 /* status set if enabled */
1166 if(ST
->mode
& 0x04) FM_STATUS_SET(ST
,0x01);
1167 /* clear or reload the counter */
1168 if (ST
->timermodel
== FM_TIMER_INTERVAL
)
1170 ST
->TAC
= (1024-ST
->TA
);
1171 // if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,0,(double)ST->TAC,ST->TimerBase);
1175 /* Timer B Overflow */
1176 INLINE
void TimerBOver(FM_ST
*ST
)
1178 /* status set if enabled */
1179 if(ST
->mode
& 0x08) FM_STATUS_SET(ST
,0x02);
1180 /* clear or reload the counter */
1181 if (ST
->timermodel
== FM_TIMER_INTERVAL
)
1183 ST
->TBC
= ( 256-ST
->TB
)<<4;
1184 // if (ST->Timer_Handler) (ST->Timer_Handler)(ST->index,1,(double)ST->TBC,ST->TimerBase);
1188 /* CSM Key Controll */
1189 INLINE
void CSMKeyControll(FM_CH
*CH
)
1191 int ksl
= KSL
[CH
->kcode
];
1193 FM_KEYOFF(CH
,SLOT1
);
1194 FM_KEYOFF(CH
,SLOT2
);
1195 FM_KEYOFF(CH
,SLOT3
);
1196 FM_KEYOFF(CH
,SLOT4
);
1197 /* total level latch */
1198 CH
->SLOT
[SLOT1
].TLL
= CH
->SLOT
[SLOT1
].TL
+ ksl
;
1199 CH
->SLOT
[SLOT2
].TLL
= CH
->SLOT
[SLOT2
].TL
+ ksl
;
1200 CH
->SLOT
[SLOT3
].TLL
= CH
->SLOT
[SLOT3
].TL
+ ksl
;
1201 CH
->SLOT
[SLOT4
].TLL
= CH
->SLOT
[SLOT4
].TL
+ ksl
;
1209 #ifdef INTERNAL_TIMER
1210 /* ---------- calcrate timer A ---------- */
1211 INLINE
void CALC_TIMER_A( FM_ST
*ST
, FM_CH
*CSM_CH
){
1212 if( ST
->TAC
&& (ST
->Timer_Handler
==0) )
1213 if( (ST
->TAC
-= ST
->freqbase
) <= 0 ){
1215 /* CSM mode key,TL controll */
1216 if( ST
->mode
& 0x80 ){ /* CSM mode total level latch and auto key on */
1217 CSMKeyControll( CSM_CH
);
1221 /* ---------- calcrate timer B ---------- */
1222 INLINE
void CALC_TIMER_B( FM_ST
*ST
,int step
){
1223 if( ST
->TBC
&& (ST
->Timer_Handler
==0) )
1224 if( (ST
->TBC
-= ST
->freqbase
*step
) <= 0 ){
1228 #endif /* INTERNAL_TIMER */
1231 /* ---------- priscaler set(and make time tables) ---------- */
1232 void OPNSetPris(FM_OPN
*OPN
, int pris
, int TimerPris
, int SSGpris
)
1236 /* frequency base */
1237 OPN
->ST
.freqbase
= (OPN
->ST
.rate
) ? ((double)OPN
->ST
.clock
* 4096.0 / OPN
->ST
.rate
) / pris
: 0;
1238 /* Timer base time */
1239 OPN
->ST
.TimerBase
= (OPN
->ST
.rate
) ? 1.0/((double)OPN
->ST
.clock
/ (double)TimerPris
) : 0;
1240 /* SSG part priscaler set */
1241 //if( SSGpris ) SSGClk( OPN->ST.index, OPN->ST.clock * 2 / SSGpris );
1242 /* make time tables */
1243 init_timetables( &OPN
->ST
, OPN_DTTABLE
, OPN_ARRATE
, OPN_DRRATE
);
1244 /* make fnumber -> increment counter table */
1245 for( fn
=0 ; fn
< 2048 ; fn
++ )
1247 /* it is freq table for octave 7 */
1248 /* opn freq counter = 20bit */
1249 OPN
->FN_TABLE
[fn
] = (double)fn
* OPN
->ST
.freqbase
/ 4096 * FREQ_RATE
* (1<<7) / 2;
1251 /* Log(LOG_INF,"OPN %d set priscaler %d\n",OPN->ST.index,pris);*/
1254 /* ---------- write a OPN mode register 0x20-0x2f ---------- */
1255 static void OPNWriteMode(FM_OPN
*OPN
, int r
, int v
)
1261 case 0x21: /* Test */
1263 case 0x22: /* LFO FREQ (YM2608/YM2612) */
1264 /* 3.98Hz,5.56Hz,6.02Hz,6.37Hz,6.88Hz,9.63Hz,48.1Hz,72.2Hz */
1265 /* FM2608[n].LFOIncr = FM2608[n].LFO_TABLE[v&0x0f]; */
1267 case 0x24: /* timer A High 8*/
1268 OPN
->ST
.TA
= (OPN
->ST
.TA
& 0x03)|(((int)v
)<<2);
1270 case 0x25: /* timer A Low 2*/
1271 OPN
->ST
.TA
= (OPN
->ST
.TA
& 0x3fc)|(v
&3);
1273 case 0x26: /* timer B */
1276 case 0x27: /* mode , timer controll */
1277 FMSetMode( &(OPN
->ST
),OPN
->ST
.index
,v
);
1279 case 0x28: /* key on / off */
1282 if( (v
&0x04) && (OPN
->type
& TYPE_6CH
) ) c
+=3;
1286 if( c
== 2 && (OPN
->ST
.mode
& 0x80) ) break;
1287 if(v
&0x10) FM_KEYON(CH
,SLOT1
); else FM_KEYOFF(CH
,SLOT1
);
1288 if(v
&0x20) FM_KEYON(CH
,SLOT2
); else FM_KEYOFF(CH
,SLOT2
);
1289 if(v
&0x40) FM_KEYON(CH
,SLOT3
); else FM_KEYOFF(CH
,SLOT3
);
1290 if(v
&0x80) FM_KEYON(CH
,SLOT4
); else FM_KEYOFF(CH
,SLOT4
);
1291 /* Log(LOG_INF,"OPN %d:%d : KEY %02X\n",n,c,v&0xf0);*/
1296 /* ---------- write a OPN register (0x30-0xff) ---------- */
1297 static void OPNWriteReg(FM_OPN
*OPN
, int r
, int v
)
1304 if( (c
= OPN_CHAN(r
)) == 3 ) return; /* 0xX3,0xX7,0xXB,0xXF */
1305 if( (r
>= 0x100) /* && (OPN->type & TYPE_6CH) */ ) c
+=3;
1309 SLOT
= &(CH
->SLOT
[OPN_SLOT(r
)]);
1310 switch( r
& 0xf0 ) {
1311 case 0x30: /* DET , MUL */
1312 set_det_mul(&OPN
->ST
,CH
,SLOT
,v
);
1315 set_tl(CH
,SLOT
,v
,(c
== 2) && (OPN
->ST
.mode
& 0x80) );
1317 case 0x50: /* KS, AR */
1318 set_ar_ksr(CH
,SLOT
,v
,OPN
->ST
.AR_TABLE
);
1321 /* bit7 = AMS ENABLE(YM2612) */
1322 set_dr(SLOT
,v
,OPN
->ST
.DR_TABLE
);
1325 set_sr(SLOT
,v
,OPN
->ST
.DR_TABLE
);
1327 case 0x80: /* SL, RR */
1328 set_sl_rr(SLOT
,v
,OPN
->ST
.DR_TABLE
);
1330 case 0x90: /* SSG-EG */
1332 if(v
&0x08) Log(LOG_ERR
,"OPN %d,%d,%d :SSG-TYPE envelope selected (not supported )\n",OPN
->ST
.index
,c
,OPN_SLOT(r
));
1337 switch( OPN_SLOT(r
) ){
1338 case 0: /* 0xa0-0xa2 : FNUM1 */
1340 unsigned int fn
= (((unsigned int)( (CH
->fn_h
)&7))<<8) + v
;
1341 unsigned char blk
= CH
->fn_h
>>3;
1342 /* make keyscale code */
1343 CH
->kcode
= (blk
<<2)|OPN_FKTABLE
[(fn
>>7)];
1344 /* make basic increment counter 32bit = 1 cycle */
1345 CH
->fc
= OPN
->FN_TABLE
[fn
]>>(7-blk
);
1346 CH
->SLOT
[SLOT1
].Incr
=-1;
1349 case 1: /* 0xa4-0xa6 : FNUM2,BLK */
1352 case 2: /* 0xa8-0xaa : 3CH FNUM1 */
1355 unsigned int fn
= (((unsigned int)(OPN
->SL3
.fn_h
[c
]&7))<<8) + v
;
1356 unsigned char blk
= OPN
->SL3
.fn_h
[c
]>>3;
1357 /* make keyscale code */
1358 OPN
->SL3
.kcode
[c
]= (blk
<<2)|OPN_FKTABLE
[(fn
>>7)];
1359 /* make basic increment counter 32bit = 1 cycle */
1360 OPN
->SL3
.fc
[c
] = OPN
->FN_TABLE
[fn
]>>(7-blk
);
1361 (OPN
->P_CH
)[2].SLOT
[SLOT1
].Incr
=-1;
1364 case 3: /* 0xac-0xae : 3CH FNUM2,BLK */
1366 OPN
->SL3
.fn_h
[c
] = v
&0x3f;
1371 switch( OPN_SLOT(r
) ){
1372 case 0: /* 0xb0-0xb2 : FB,ALGO */
1374 int feedback
= (v
>>3)&7;
1376 CH
->FB
= feedback
? 8 - feedback
: 0;
1377 set_algorythm( CH
);
1380 case 1: /* 0xb4-0xb6 : L , R , AMS , PMS (YM2612/YM2608) */
1381 if( OPN
->type
& TYPE_LFOPAN
)
1384 /* 0,3.4,6.7,10,14,20,40,80(cent) */
1385 SLOT
->pms
= (v
>>4) & 0x07;
1387 /* 0,1.4,5.9,11.8(dB) */
1388 SLOT
->ams
= v
& 0x03;
1390 CH
->PAN
= (v
>>6)&0x03; /* PAN : b6 = R , b7 = L */
1391 set_algorythm( CH
);
1392 /* Log(LOG_INF,"OPN %d,%d : PAN %d\n",n,c,CH->PAN);*/
1400 #endif /* BUILD_OPN */
1403 /*******************************************************************************/
1404 /* YM2203 local section */
1405 /*******************************************************************************/
1406 static YM2203
*FM2203
=NULL
; /* array of YM2203's */
1408 /* ---------- update one of chip ----------- */
1409 void YM2203UpdateOne(int num
, void *buffer
, int length
)
1411 YM2203
*F2203
= &(FM2203
[num
]);
1412 FM_OPN
*OPN
= &(FM2203
[num
].OPN
);
1415 FMSAMPLE
*buf
= (FMSAMPLE
*)buffer
;
1417 State
= &F2203
->OPN
.ST
;
1418 cch
[0] = &F2203
->CH
[0];
1419 cch
[1] = &F2203
->CH
[1];
1420 cch
[2] = &F2203
->CH
[2];
1422 /* frequency counter channel A */
1423 CALC_FCOUNT( cch
[0] );
1424 /* frequency counter channel B */
1425 CALC_FCOUNT( cch
[1] );
1426 /* frequency counter channel C */
1427 if( (State
->mode
& 0xc0) ){
1429 if( cch
[2]->SLOT
[SLOT1
].Incr
==-1){
1431 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT1
] , OPN
->SL3
.fc
[1] , OPN
->SL3
.kcode
[1] );
1432 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT2
] , OPN
->SL3
.fc
[2] , OPN
->SL3
.kcode
[2] );
1433 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT3
] , OPN
->SL3
.fc
[0] , OPN
->SL3
.kcode
[0] );
1434 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT4
] , cch
[2]->fc
, cch
[2]->kcode
);
1436 }else CALC_FCOUNT( cch
[2] );
1438 for( i
=0; i
< length
; i
++ )
1440 /* channel A channel B channel C */
1441 outd
[OPN_CENTER
] = 0;
1443 for( ch
=0;ch
<3;ch
++) FM_CALC_CH( cch
[ch
] );
1445 data
= Limit( outd
[OPN_CENTER
] , OPN_MAXOUT
, OPN_MINOUT
);
1446 /* store to sound buffer */
1447 buf
[i
] = data
>> OPN_OUTSB
;
1448 #ifdef INTERNAL_TIMER
1449 /* timer controll */
1450 CALC_TIMER_A( State
, cch
[2] );
1453 #ifdef INTERNAL_TIMER
1454 CALC_TIMER_B( State
, length
);
1458 /* ---------- reset one of chip ---------- */
1459 void YM2203ResetChip(int num
)
1462 FM_OPN
*OPN
= &(FM2203
[num
].OPN
);
1464 /* Reset Priscaler */
1465 OPNSetPris( OPN
, 6*12 , 6*12 ,4); /* 1/6 , 1/4 */
1466 /* reset SSG section */
1467 //SSGReset(OPN->ST.index);
1469 FM_IRQMASK_SET(&OPN
->ST
,0x03);
1470 OPNWriteMode(OPN
,0x27,0x30); /* mode 0 , timer reset */
1471 reset_channel( &OPN
->ST
, FM2203
[num
].CH
, 3 );
1472 /* reset OPerator paramater */
1473 for(i
= 0xb6 ; i
>= 0xb4 ; i
-- ) OPNWriteReg(OPN
,i
,0xc0); /* PAN RESET */
1474 for(i
= 0xb2 ; i
>= 0x30 ; i
-- ) OPNWriteReg(OPN
,i
,0);
1475 for(i
= 0x26 ; i
>= 0x20 ; i
-- ) OPNWriteReg(OPN
,i
,0);
1478 /* ---------- return the buffer ---------- */
1479 FMSAMPLE
*YM2203Buffer(int n
)
1481 return FM2203
[n
].Buf
;
1484 /* ---------- set buffer ---------- */
1485 int YM2203SetBuffer(int n
, FMSAMPLE
*buf
)
1487 if( buf
== 0 ) return -1;
1488 FM2203
[n
].Buf
= buf
;
1493 /* ---------- Initialize YM2203 emulator(s) ---------- */
1494 /* 'num' is the number of virtual YM2203's to allocate */
1495 /* 'rate' is sampling rate and 'bufsiz' is the size of the */
1496 /* buffer that should be updated at each interval */
1497 int YM2203Init(int num
, int clock
, int rate
,
1498 FM_TIMERHANDLER TimerHandler
,FM_IRQHANDLER IRQHandler
)
1502 if (FM2203
) return (-1); /* duplicate init. */
1503 cur_chip
= NULL
; /* hiro-shi!! */
1507 /* allocate ym2203 state space */
1508 if( (FM2203
= (YM2203
*)malloc(sizeof(YM2203
) * FMNumChips
))==NULL
)
1511 memset(FM2203
,0,sizeof(YM2203
) * FMNumChips
);
1512 /* allocate total level table (128kb space) */
1513 if( !FMInitTable() )
1519 for ( i
= 0 ; i
< FMNumChips
; i
++ ) {
1520 FM2203
[i
].OPN
.ST
.index
= i
;
1521 FM2203
[i
].OPN
.type
= TYPE_YM2203
;
1522 FM2203
[i
].OPN
.P_CH
= FM2203
[i
].CH
;
1523 FM2203
[i
].OPN
.ST
.clock
= clock
;
1524 FM2203
[i
].OPN
.ST
.rate
= rate
;
1525 /* FM2203[i].OPN.ST.irq = 0; */
1526 /* FM2203[i].OPN.ST.satus = 0; */
1527 FM2203
[i
].OPN
.ST
.timermodel
= FM_TIMER_SINGLE
;
1528 /* Extend handler */
1529 FM2203
[i
].OPN
.ST
.Timer_Handler
= TimerHandler
;
1530 FM2203
[i
].OPN
.ST
.IRQ_Handler
= IRQHandler
;
1536 /* ---------- shut down emurator ----------- */
1537 void YM2203Shutdown(void)
1539 if (!FM2203
) return;
1546 /* ---------- YM2203 I/O interface ---------- */
1547 int YM2203Write(int n
,int a
,int v
)
1549 FM_OPN
*OPN
= &(FM2203
[n
].OPN
);
1552 { /* address port */
1553 OPN
->ST
.address
= v
& 0xff;
1554 /* Write register to SSG emurator */
1555 //if( v < 16 ) SSGWrite(n,0,v);
1556 switch(OPN
->ST
.address
)
1558 case 0x2d: /* divider sel */
1559 OPNSetPris( OPN
, 6*12, 6*12 ,4); /* OPN 1/6 , SSG 1/4 */
1561 case 0x2e: /* divider sel */
1562 OPNSetPris( OPN
, 3*12, 3*12,2); /* OPN 1/3 , SSG 1/2 */
1564 case 0x2f: /* divider sel */
1565 OPNSetPris( OPN
, 2*12, 2*12,1); /* OPN 1/2 , SSG 1/1 */
1571 int addr
= OPN
->ST
.address
;
1572 switch( addr
& 0xf0 )
1574 case 0x00: /* 0x00-0x0f : SSG section */
1575 /* Write data to SSG emurator */
1578 case 0x20: /* 0x20-0x2f : Mode section */
1579 //YM2203UpdateReq(n);
1580 /* write register */
1581 OPNWriteMode(OPN
,addr
,v
);
1583 default: /* 0x30-0xff : OPN section */
1584 //YM2203UpdateReq(n);
1585 /* write register */
1586 OPNWriteReg(OPN
,addr
,v
);
1592 unsigned char YM2203Read(int n
,int a
)
1594 YM2203
*F2203
= &(FM2203
[n
]);
1595 int addr
= F2203
->OPN
.ST
.address
;
1600 ret
= F2203
->OPN
.ST
.status
;
1603 { /* data port (ONLY SSG) */
1604 //if( addr < 16 ) ret = SSGRead(n);
1609 int YM2203TimerOver(int n
,int c
)
1611 YM2203
*F2203
= &(FM2203
[n
]);
1615 TimerBOver( &(F2203
->OPN
.ST
) );
1619 //YM2203UpdateReq(n);
1621 TimerAOver( &(F2203
->OPN
.ST
) );
1622 /* CSM mode key,TL controll */
1623 if( F2203
->OPN
.ST
.mode
& 0x80 )
1624 { /* CSM mode total level latch and auto key on */
1625 CSMKeyControll( &(F2203
->CH
[2]) );
1628 return F2203
->OPN
.ST
.irq
;
1631 #endif /* BUILD_YM2203 */
1639 /*******************************************************************************/
1640 /* YM2612 local section */
1641 /*******************************************************************************/
1642 static YM2612
*FM2612
=NULL
; /* array of YM2612's */
1644 /* ---------- update one of chip ----------- */
1645 void YM2612UpdateOne(int num
, void **buffer
, int length
)
1647 YM2612
*F2612
= &(FM2612
[num
]);
1648 FM_OPN
*OPN
= &(FM2612
[num
].OPN
);
1651 int dacen
= F2612
->dacen
;
1652 int dacout
= F2612
->dacout
;
1655 bufL
= (FMSAMPLE
*)buffer
[0];
1656 bufR
= (FMSAMPLE
*)buffer
[1];
1658 if( (void *)F2612
!= cur_chip
){
1659 cur_chip
= (void *)F2612
;
1662 cch
[0] = &F2612
->CH
[0];
1663 cch
[1] = &F2612
->CH
[1];
1664 cch
[2] = &F2612
->CH
[2];
1665 cch
[3] = &F2612
->CH
[3];
1666 cch
[4] = &F2612
->CH
[4];
1667 cch
[5] = &F2612
->CH
[5];
1669 /* update frequency counter */
1670 CALC_FCOUNT( cch
[0] );
1671 CALC_FCOUNT( cch
[1] );
1672 if( (State
->mode
& 0xc0) ){
1674 if( cch
[2]->SLOT
[SLOT1
].Incr
==-1){
1676 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT1
] , OPN
->SL3
.fc
[1] , OPN
->SL3
.kcode
[1] );
1677 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT2
] , OPN
->SL3
.fc
[2] , OPN
->SL3
.kcode
[2] );
1678 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT3
] , OPN
->SL3
.fc
[0] , OPN
->SL3
.kcode
[0] );
1679 CALC_FCSLOT(&cch
[2]->SLOT
[SLOT4
] , cch
[2]->fc
, cch
[2]->kcode
);
1681 }else CALC_FCOUNT( cch
[2] );
1682 CALC_FCOUNT( cch
[3] );
1683 CALC_FCOUNT( cch
[4] );
1684 CALC_FCOUNT( cch
[5] );
1686 for( i
=0; i
< length
; i
++ )
1688 /* clear output acc. */
1689 outd
[OPN_LEFT
] = outd
[OPN_RIGHT
]= outd
[OPN_CENTER
] = 0;
1690 /* calcrate channel output */
1691 for( ch
=0;ch
<5;ch
++) FM_CALC_CH( cch
[ch
] );
1692 dacout
=0; // dave temporary
1693 if( dacen
) *cch
[5]->connect4
+= dacout
;
1694 else FM_CALC_CH( cch
[5] );
1695 /* get left & right output */
1696 dataL
= Limit( outd
[OPN_CENTER
] + outd
[OPN_LEFT
], OPN_MAXOUT
, OPN_MINOUT
);
1697 dataR
= Limit( outd
[OPN_CENTER
] + outd
[OPN_RIGHT
], OPN_MAXOUT
, OPN_MINOUT
);
1699 #ifdef FM_STEREO_MIX /* stereo mixing */
1701 ((FMSAMPLE_MIX
*)bufL
)[i
] += ((dataL
>>OPN_OUTSB
)<<FM_OUTPUT_BIT
)|(dataR
>>OPN_OUTSB
);
1703 /* stereo separate */
1704 bufL
[i
] += ((dataL
>>OPN_OUTSB
)*3)>>2; // Dave: adds it in 3/4
1705 bufR
[i
] += ((dataR
>>OPN_OUTSB
)*3)>>2;
1711 #ifdef INTERNAL_TIMER
1712 /* timer controll */
1713 CALC_TIMER_A( State
, cch
[2] );
1716 #ifdef INTERNAL_TIMER
1717 CALC_TIMER_B( State
, length
);
1721 /* -------------------------- YM2612 ---------------------------------- */
1722 int YM2612Init(int num
, int clock
, int rate
,
1723 FM_TIMERHANDLER TimerHandler
,FM_IRQHANDLER IRQHandler
)
1727 if (FM2612
) return (-1); /* duplicate init. */
1728 cur_chip
= NULL
; /* hiro-shi!! */
1732 /* allocate extend state space */
1733 if( (FM2612
= (YM2612
*)malloc(sizeof(YM2612
) * FMNumChips
))==NULL
)
1736 memset(FM2612
,0,sizeof(YM2612
) * FMNumChips
);
1737 /* allocate total level table (128kb space) */
1738 if( !FMInitTable() )
1744 for ( i
= 0 ; i
< FMNumChips
; i
++ ) {
1745 FM2612
[i
].OPN
.ST
.index
= i
;
1746 FM2612
[i
].OPN
.type
= TYPE_YM2612
;
1747 FM2612
[i
].OPN
.P_CH
= FM2612
[i
].CH
;
1748 FM2612
[i
].OPN
.ST
.clock
= clock
;
1749 FM2612
[i
].OPN
.ST
.rate
= rate
;
1750 /* FM2612[i].OPN.ST.irq = 0; */
1751 /* FM2612[i].OPN.ST.status = 0; */
1752 FM2612
[i
].OPN
.ST
.timermodel
= FM_TIMER_SINGLE
;
1753 /* Extend handler */
1754 FM2612
[i
].OPN
.ST
.Timer_Handler
= TimerHandler
;
1755 FM2612
[i
].OPN
.ST
.IRQ_Handler
= IRQHandler
;
1761 /* ---------- shut down emurator ----------- */
1762 void YM2612Shutdown()
1764 if (!FM2612
) return;
1771 /* ---------- reset one of chip ---------- */
1772 void YM2612ResetChip(int num
)
1775 YM2612
*F2612
= &(FM2612
[num
]);
1776 FM_OPN
*OPN
= &(FM2612
[num
].OPN
);
1778 OPNSetPris( OPN
, 12*12, 12*12, 0);
1780 FM_IRQMASK_SET(&OPN
->ST
,0x03);
1781 OPNWriteMode(OPN
,0x27,0x30); /* mode 0 , timer reset */
1783 reset_channel( &OPN
->ST
, &F2612
->CH
[0] , 6 );
1785 for(i
= 0xb6 ; i
>= 0xb4 ; i
-- )
1787 OPNWriteReg(OPN
,i
,0xc0);
1788 OPNWriteReg(OPN
,i
|0x100,0xc0);
1790 for(i
= 0xb2 ; i
>= 0x30 ; i
-- )
1792 OPNWriteReg(OPN
,i
,0);
1793 OPNWriteReg(OPN
,i
|0x100,0);
1795 for(i
= 0x26 ; i
>= 0x20 ; i
-- ) OPNWriteReg(OPN
,i
,0);
1796 /* DAC mode clear */
1804 int YM2612Write(int n
, int a
,int v
)
1806 YM2612
*F2612
= &(FM2612
[n
]);
1810 case 0: /* address port 0 */
1811 F2612
->OPN
.ST
.address
= v
& 0xff;
1813 case 1: /* data port 0 */
1814 addr
= F2612
->OPN
.ST
.address
;
1815 switch( addr
& 0xf0 )
1817 case 0x20: /* 0x20-0x2f Mode */
1820 case 0x2a: /* DAC data (YM2612) */
1821 //YM2612UpdateReq(n);
1822 F2612
->dacout
= v
<<(TL_BITS
-8);
1824 extern int mega_dacout
;
1828 case 0x2b: /* DAC Sel (YM2612) */
1829 /* b7 = dac enable */
1830 F2612
->dacen
= v
& 0x80;
1832 extern int mega_dacen
;
1838 default: /* OPN section */
1839 //YM2612UpdateReq(n);
1840 /* write register */
1841 OPNWriteMode(&(F2612
->OPN
),addr
,v
);
1844 default: /* 0x30-0xff OPN section */
1845 //YM2612UpdateReq(n);
1846 /* write register */
1847 OPNWriteReg(&(F2612
->OPN
),addr
,v
);
1850 case 2: /* address port 1 */
1851 F2612
->address1
= v
& 0xff;
1853 case 3: /* data port 1 */
1854 addr
= F2612
->address1
;
1855 //YM2612UpdateReq(n);
1856 OPNWriteReg(&(F2612
->OPN
),addr
|0x100,v
);
1859 return F2612
->OPN
.ST
.irq
;
1861 unsigned char YM2612Read(int n
,int a
)
1863 YM2612
*F2612
= &(FM2612
[n
]);
1864 int addr
= F2612
->OPN
.ST
.address
;
1867 case 0: /* status 0 */
1868 return F2612
->OPN
.ST
.status
;
1872 Log(LOG_WAR
,"YM2612 #%d:A=%d read unmapped area\n");
1873 return F2612
->OPN
.ST
.status
;
1878 int YM2612TimerOver(int n
,int c
)
1880 YM2612
*F2612
= &(FM2612
[n
]);
1884 TimerBOver( &(F2612
->OPN
.ST
) );
1888 //YM2612UpdateReq(n);
1890 TimerAOver( &(F2612
->OPN
.ST
) );
1891 /* CSM mode key,TL controll */
1892 if( F2612
->OPN
.ST
.mode
& 0x80 )
1893 { /* CSM mode total level latch and auto key on */
1894 CSMKeyControll( &(F2612
->CH
[2]) );
1897 return F2612
->OPN
.ST
.irq
;
1901 /* ---------- set buffer ---------- */
1902 int YM2612SetBuffer(int n
, FMSAMPLE
**buf
)
1905 for( i
= 0 ; i
< YM2612_NUMBUF
; i
++){
1906 FM2612
[n
].Buf
[i
] = buf
[i
];
1907 if( cur_chip
== &FM2612
[n
] ) cur_chip
= NULL
;
1913 #endif /* BUILD_YM2612 */