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