33
#include "qemu/osdep.h"
38
#define PI 3.14159265358979323846
44
static FILE *opl_dbg_fp = NULL;
45
static FM_OPL *opl_dbg_opl[16];
46
static int opl_dbg_maxchip,opl_dbg_chip;
51
#define OPL_ARRATE 141280
52
#define OPL_DRRATE 1956000
54
#define DELTAT_MIXING_LEVEL (1)
59
#define FREQ_RATE (1<<(FREQ_BITS-20))
60
#define TL_BITS (FREQ_BITS+2)
63
#define OPL_OUTSB (TL_BITS+3-16)
64
#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
65
#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
81
#define EG_OFF ((2*EG_ENT)<<ENV_BITS)
83
#define EG_DST (EG_ENT<<ENV_BITS)
87
#define EG_STEP (96.0/EG_ENT)
91
#define VIB_SHIFT (32-9)
93
#define AMS_SHIFT (32-9)
104
#define ENV_MOD_RR 0x00
105
#define ENV_MOD_DR 0x01
106
#define ENV_MOD_AR 0x02
109
static const int slot_array[32]=
111
0, 2, 4, 1, 3, 5,-1,-1,
112
6, 8,10, 7, 9,11,-1,-1,
113
12,14,16,13,15,17,-1,-1,
114
-1,-1,-1,-1,-1,-1,-1,-1
119
#define DV (EG_STEP/2)
120
static const uint32_t KSL_TABLE[8*16]=
123
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
124
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
125
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
126
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
128
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
129
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
130
0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
131
1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
133
0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
134
0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
135
3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
136
4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
138
0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
139
3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
140
6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
141
7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
143
0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
144
6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
145
9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
146
10.875/DV,11.250/DV,11.625/DV,12.000/DV,
148
0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
149
9.000/DV,10.125/DV,10.875/DV,11.625/DV,
150
12.000/DV,12.750/DV,13.125/DV,13.500/DV,
151
13.875/DV,14.250/DV,14.625/DV,15.000/DV,
153
0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
154
12.000/DV,13.125/DV,13.875/DV,14.625/DV,
155
15.000/DV,15.750/DV,16.125/DV,16.500/DV,
156
16.875/DV,17.250/DV,17.625/DV,18.000/DV,
158
0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
159
15.000/DV,16.125/DV,16.875/DV,17.625/DV,
160
18.000/DV,18.750/DV,19.125/DV,19.500/DV,
161
19.875/DV,20.250/DV,20.625/DV,21.000/DV
167
#define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
168
static const int32_t SL_TABLE[16]={
169
SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
170
SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
174
#define TL_MAX (EG_ENT*2)
178
static int32_t *TL_TABLE;
181
static int32_t **SIN_TABLE;
184
static int32_t *AMS_TABLE;
185
static int32_t *VIB_TABLE;
189
static int32_t *ENV_CURVE;
193
static const uint32_t MUL_TABLE[16]= {
195
0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
196
8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
201
static int32_t RATE_0[16]=
202
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
207
static int num_lock = 0;
210
static void *cur_chip = NULL;
215
static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
217
static int32_t outd[1];
220
static int32_t *ams_table;
221
static int32_t *vib_table;
222
static int32_t amsIncr;
223
static int32_t vibIncr;
224
static int32_t feedback2;
232
#define LOG_LEVEL LOG_ERR
239
static inline int Limit( int val, int max, int min ) {
242
else if ( val < min )
249
static inline void OPL_STATUS_SET(FM_OPL *OPL,int flag)
253
if(!(OPL->status & 0x80))
255
if(OPL->status & OPL->statusmask)
263
static inline void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
267
if((OPL->status & 0x80))
269
if (!(OPL->status & OPL->statusmask) )
277
static inline void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
279
OPL->statusmask = flag;
281
OPL_STATUS_SET(OPL,0);
282
OPL_STATUS_RESET(OPL,0);
286
static inline void OPL_KEYON(OPL_SLOT *SLOT)
291
SLOT->evm = ENV_MOD_AR;
292
SLOT->evs = SLOT->evsa;
297
static inline void OPL_KEYOFF(OPL_SLOT *SLOT)
299
if( SLOT->evm > ENV_MOD_RR)
302
SLOT->evm = ENV_MOD_RR;
303
if( !(SLOT->evc&EG_DST) )
307
SLOT->evs = SLOT->evsr;
313
static inline uint32_t OPL_CALC_SLOT( OPL_SLOT *SLOT )
316
if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
321
SLOT->evm = ENV_MOD_DR;
323
SLOT->eve = SLOT->SL;
324
SLOT->evs = SLOT->evsd;
327
SLOT->evc = SLOT->SL;
335
SLOT->evm = ENV_MOD_RR;
336
SLOT->evs = SLOT->evsr;
341
SLOT->eve = EG_OFF+1;
347
return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
351
static void set_algorithm( OPL_CH *CH)
353
int32_t *carrier = &outd[0];
354
CH->connect1 = CH->CON ? carrier : &feedback2;
355
CH->connect2 = carrier;
359
static inline void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
364
SLOT->Incr = CH->fc * SLOT->mul;
365
ksr = CH->kcode >> SLOT->KSR;
367
if( SLOT->ksr != ksr )
371
SLOT->evsa = SLOT->AR[ksr];
372
SLOT->evsd = SLOT->DR[ksr];
373
SLOT->evsr = SLOT->RR[ksr];
375
SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
379
static inline void set_mul(FM_OPL *OPL,int slot,int v)
381
OPL_CH *CH = &OPL->P_CH[slot/2];
382
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
384
SLOT->mul = MUL_TABLE[v&0x0f];
385
SLOT->KSR = (v&0x10) ? 0 : 2;
386
SLOT->eg_typ = (v&0x20)>>5;
387
SLOT->vib = (v&0x40);
388
SLOT->ams = (v&0x80);
389
CALC_FCSLOT(CH,SLOT);
393
static inline void set_ksl_tl(FM_OPL *OPL,int slot,int v)
395
OPL_CH *CH = &OPL->P_CH[slot/2];
396
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
399
SLOT->ksl = ksl ? 3-ksl : 31;
400
SLOT->TL = (v&0x3f)*(0.75/EG_STEP);
402
if( !(OPL->mode&0x80) )
404
SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
409
static inline void set_ar_dr(FM_OPL *OPL,int slot,int v)
411
OPL_CH *CH = &OPL->P_CH[slot/2];
412
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
416
SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
417
SLOT->evsa = SLOT->AR[SLOT->ksr];
418
if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
420
SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
421
SLOT->evsd = SLOT->DR[SLOT->ksr];
422
if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
426
static inline void set_sl_rr(FM_OPL *OPL,int slot,int v)
428
OPL_CH *CH = &OPL->P_CH[slot/2];
429
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
433
SLOT->SL = SL_TABLE[sl];
434
if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
435
SLOT->RR = &OPL->DR_TABLE[rr<<2];
436
SLOT->evsr = SLOT->RR[SLOT->ksr];
437
if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
441
#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
443
static inline void OPL_CALC_CH( OPL_CH *CH )
450
SLOT = &CH->SLOT[SLOT1];
451
env_out=OPL_CALC_SLOT(SLOT);
452
if( env_out < EG_ENT-1 )
455
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
456
else SLOT->Cnt += SLOT->Incr;
460
int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
461
CH->op1_out[1] = CH->op1_out[0];
462
*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
466
*CH->connect1 += OP_OUT(SLOT,env_out,0);
470
CH->op1_out[1] = CH->op1_out[0];
474
SLOT = &CH->SLOT[SLOT2];
475
env_out=OPL_CALC_SLOT(SLOT);
476
if( env_out < EG_ENT-1 )
479
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
480
else SLOT->Cnt += SLOT->Incr;
482
outd[0] += OP_OUT(SLOT,env_out, feedback2);
487
#define WHITE_NOISE_db 6.0
488
static inline void OPL_CALC_RH( OPL_CH *CH )
490
uint32_t env_tam,env_sd,env_top,env_hh;
491
int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
500
SLOT = &CH[6].SLOT[SLOT1];
501
env_out=OPL_CALC_SLOT(SLOT);
502
if( env_out < EG_ENT-1 )
505
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
506
else SLOT->Cnt += SLOT->Incr;
510
int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
511
CH[6].op1_out[1] = CH[6].op1_out[0];
512
feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
516
feedback2 = OP_OUT(SLOT,env_out,0);
521
CH[6].op1_out[1] = CH[6].op1_out[0];
522
CH[6].op1_out[0] = 0;
525
SLOT = &CH[6].SLOT[SLOT2];
526
env_out=OPL_CALC_SLOT(SLOT);
527
if( env_out < EG_ENT-1 )
530
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
531
else SLOT->Cnt += SLOT->Incr;
533
outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
540
env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
541
env_tam=OPL_CALC_SLOT(SLOT8_1);
542
env_top=OPL_CALC_SLOT(SLOT8_2);
543
env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
546
if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
547
else SLOT7_1->Cnt += 2*SLOT7_1->Incr;
548
if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
549
else SLOT7_2->Cnt += (CH[7].fc*8);
550
if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
551
else SLOT8_1->Cnt += SLOT8_1->Incr;
552
if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
553
else SLOT8_2->Cnt += (CH[8].fc*48);
555
tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
558
if( env_sd < EG_ENT-1 )
559
outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
561
if( env_tam < EG_ENT-1 )
562
outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
564
if( env_top < EG_ENT-1 )
565
outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
567
if( env_hh < EG_ENT-1 )
568
outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
572
static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
578
for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
579
for (i = 4;i <= 60;i++){
580
rate = OPL->freqbase;
581
if( i < 60 ) rate *= 1.0+(i&3)*0.25;
582
rate *= 1<<((i>>2)-1);
583
rate *= (double)(EG_ENT<<ENV_BITS);
584
OPL->AR_TABLE[i] = rate / ARRATE;
585
OPL->DR_TABLE[i] = rate / DRRATE;
587
for (i = 60; i < ARRAY_SIZE(OPL->AR_TABLE); i++)
589
OPL->AR_TABLE[i] = EG_AED-1;
590
OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
593
for (i = 0;i < 64 ;i++){
594
LOG(LOG_WAR, ("rate %2d , ar %f ms , dr %f ms\n", i,
595
((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
596
((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
602
static int OPLOpenTable( void )
610
if( (TL_TABLE = malloc(TL_MAX*2*sizeof(int32_t))) == NULL)
612
if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(int32_t *))) == NULL)
617
if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(int32_t))) == NULL)
623
if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(int32_t))) == NULL)
630
ENV_CURVE = g_new(int32_t, 2 * EG_ENT + 1);
632
for (t = 0;t < EG_ENT-1 ;t++){
633
rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);
634
TL_TABLE[ t] = (int)rate;
635
TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
639
for ( t = EG_ENT-1; t < TL_MAX ;t++){
640
TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
645
SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
646
for (s = 1;s <= SIN_ENT/4;s++){
647
pom = sin(2*PI*s/SIN_ENT);
648
pom = 20*log10(1/pom);
652
SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
654
SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
657
for (s = 0;s < SIN_ENT;s++)
659
SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
660
SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
661
SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
665
for (i=0; i<EG_ENT; i++)
668
pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
670
ENV_CURVE[i] = (int)pom;
672
ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
675
ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
677
for (i=0; i<AMS_ENT; i++)
679
pom = (1.0+sin(2*PI*i/AMS_ENT))/2;
680
AMS_TABLE[i] = (1.0/EG_STEP)*pom;
681
AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom;
684
for (i=0; i<VIB_ENT; i++)
687
pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT);
688
VIB_TABLE[i] = VIB_RATE + (pom*0.07);
689
VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14);
696
static void OPLCloseTable( void )
706
static inline void CSMKeyControll(OPL_CH *CH)
708
OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
709
OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
714
slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
715
slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
717
CH->op1_out[0] = CH->op1_out[1] = 0;
723
static void OPL_initialize(FM_OPL *OPL)
728
OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
730
OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
732
init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
734
for( fn=0 ; fn < 1024 ; fn++ )
736
OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
739
OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
740
OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
744
static void OPLWriteReg(FM_OPL *OPL, int r, int v)
757
OPL->wavesel = v&0x20;
762
for(c=0;c<OPL->max_ch;c++)
764
OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
765
OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
770
OPL->T[0] = (256-v)*4;
773
OPL->T[1] = (256-v)*16;
778
OPL_STATUS_RESET(OPL,0x7f);
783
uint8_t st2 = (v>>1)&1;
785
OPL_STATUS_RESET(OPL,v&0x78);
786
OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
788
if(OPL->st[1] != st2)
790
double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
792
if (OPL->TimerHandler) {
793
(OPL->TimerHandler)(OPL->TimerParam, 1, interval);
797
if(OPL->st[0] != st1)
799
double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
801
if (OPL->TimerHandler) {
802
(OPL->TimerHandler)(OPL->TimerParam, 0, interval);
810
slot = slot_array[r&0x1f];
811
if(slot == -1) return;
815
slot = slot_array[r&0x1f];
816
if(slot == -1) return;
817
set_ksl_tl(OPL,slot,v);
820
slot = slot_array[r&0x1f];
821
if(slot == -1) return;
822
set_ar_dr(OPL,slot,v);
825
slot = slot_array[r&0x1f];
826
if(slot == -1) return;
827
set_sl_rr(OPL,slot,v);
835
uint8_t rkey = OPL->rhythm^v;
836
OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
837
OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
838
OPL->rhythm = v&0x3f;
842
usrintf_showmessage("OPL Rhythm mode select");
849
OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
850
OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
851
OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
855
OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
856
OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
862
if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
863
else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
867
if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
868
else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
873
if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
874
else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
879
if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
880
else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
887
if( (r&0x0f) > 8) return;
888
CH = &OPL->P_CH[r&0x0f];
891
block_fnum = (CH->block_fnum&0x1f00) | v;
895
int keyon = (v>>5)&1;
896
block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
897
if(CH->keyon != keyon)
899
if( (CH->keyon=keyon) )
901
CH->op1_out[0] = CH->op1_out[1] = 0;
902
OPL_KEYON(&CH->SLOT[SLOT1]);
903
OPL_KEYON(&CH->SLOT[SLOT2]);
907
OPL_KEYOFF(&CH->SLOT[SLOT1]);
908
OPL_KEYOFF(&CH->SLOT[SLOT2]);
913
if(CH->block_fnum != block_fnum)
915
int blockRv = 7-(block_fnum>>10);
916
int fnum = block_fnum&0x3ff;
917
CH->block_fnum = block_fnum;
919
CH->ksl_base = KSL_TABLE[block_fnum>>6];
920
CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
921
CH->kcode = CH->block_fnum>>9;
922
if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
923
CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
924
CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
929
if( (r&0x0f) > 8) return;
930
CH = &OPL->P_CH[r&0x0f];
932
int feedback = (v>>1)&7;
933
CH->FB = feedback ? (8+1) - feedback : 0;
939
slot = slot_array[r&0x1f];
940
if(slot == -1) return;
941
CH = &OPL->P_CH[slot/2];
945
CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
952
static int OPL_LockTable(void)
955
if(num_lock>1) return 0;
959
if( !OPLOpenTable() )
967
static void OPL_UnLockTable(void)
969
if(num_lock) num_lock--;
981
void YM3812UpdateOne(FM_OPL *OPL, int16_t *buffer, int length)
985
int16_t *buf = buffer;
986
uint32_t amsCnt = OPL->amsCnt;
987
uint32_t vibCnt = OPL->vibCnt;
988
uint8_t rhythm = OPL->rhythm&0x20;
991
if( (void *)OPL != cur_chip ){
992
cur_chip = (void *)OPL;
997
SLOT7_1 = &S_CH[7].SLOT[SLOT1];
998
SLOT7_2 = &S_CH[7].SLOT[SLOT2];
999
SLOT8_1 = &S_CH[8].SLOT[SLOT1];
1000
SLOT8_2 = &S_CH[8].SLOT[SLOT2];
1002
amsIncr = OPL->amsIncr;
1003
vibIncr = OPL->vibIncr;
1004
ams_table = OPL->ams_table;
1005
vib_table = OPL->vib_table;
1007
R_CH = rhythm ? &S_CH[6] : E_CH;
1008
for( i=0; i < length ; i++ )
1012
ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
1013
vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
1016
for(CH=S_CH ; CH < R_CH ; CH++)
1022
data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
1024
buf[i] = data >> OPL_OUTSB;
1027
OPL->amsCnt = amsCnt;
1028
OPL->vibCnt = vibCnt;
1029
#ifdef OPL_OUTPUT_LOG
1032
for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
1033
if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
1034
fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
1040
static void OPLResetChip(FM_OPL *OPL)
1047
OPL_STATUS_RESET(OPL,0x7f);
1049
OPLWriteReg(OPL,0x01,0);
1050
OPLWriteReg(OPL,0x02,0);
1051
OPLWriteReg(OPL,0x03,0);
1052
OPLWriteReg(OPL,0x04,0);
1053
for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
1055
for( c = 0 ; c < OPL->max_ch ; c++ )
1057
OPL_CH *CH = &OPL->P_CH[c];
1059
for(s = 0 ; s < 2 ; s++ )
1062
CH->SLOT[s].wavetable = &SIN_TABLE[0];
1064
CH->SLOT[s].evc = EG_OFF;
1065
CH->SLOT[s].eve = EG_OFF+1;
1066
CH->SLOT[s].evs = 0;
1073
FM_OPL *OPLCreate(int clock, int rate)
1080
if( OPL_LockTable() ==-1) return NULL;
1082
state_size = sizeof(FM_OPL);
1083
state_size += sizeof(OPL_CH)*max_ch;
1085
ptr = malloc(state_size);
1086
if(ptr==NULL) return NULL;
1088
memset(ptr,0,state_size);
1089
OPL = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
1090
OPL->P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
1094
OPL->max_ch = max_ch;
1096
OPL_initialize(OPL);
1099
#ifdef OPL_OUTPUT_LOG
1102
opl_dbg_fp = fopen("opllog.opl","wb");
1103
opl_dbg_maxchip = 0;
1107
opl_dbg_opl[opl_dbg_maxchip] = OPL;
1108
fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
1112
(clock/0x10000)&0xff,
1113
(clock/0x1000000)&0xff);
1121
void OPLDestroy(FM_OPL *OPL)
1123
#ifdef OPL_OUTPUT_LOG
1136
void OPLSetTimerHandler(FM_OPL *OPL, OPL_TIMERHANDLER TimerHandler,
1139
OPL->TimerHandler = TimerHandler;
1140
OPL->TimerParam = param;
1144
int OPLWrite(FM_OPL *OPL,int a,int v)
1148
OPL->address = v & 0xff;
1152
#ifdef OPL_OUTPUT_LOG
1155
for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
1156
if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
1157
fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
1160
OPLWriteReg(OPL,OPL->address,v);
1162
return OPL->status>>7;
1165
unsigned char OPLRead(FM_OPL *OPL,int a)
1169
return OPL->status & (OPL->statusmask|0x80);
1172
switch(OPL->address)
1188
int OPLTimerOver(FM_OPL *OPL,int c)
1192
OPL_STATUS_SET(OPL,0x20);
1196
OPL_STATUS_SET(OPL,0x40);
1198
if( OPL->mode & 0x80 )
1202
CSMKeyControll( &OPL->P_CH[ch] );
1206
if (OPL->TimerHandler) {
1207
(OPL->TimerHandler)(OPL->TimerParam, c,
1208
(double)OPL->T[c] * OPL->TimerBase);
1210
return OPL->status>>7;