2 // Jarek Burczynski's YM2151 emulator
4 // Cleaned of most MAMEisms & cleaned up in general by James Hammons
5 // (this is mostly a placeholder until I write my own)
17 // Missing shit (from M.A.M.E.)
20 #define PI 3.1415629535897932338
21 static FILE * errorlog = 0;
22 //int cpu_scalebyfcount(int);
23 //void timer_remove(void *);
24 //void * timer_set(int, int, void (*)(int));
26 // Bogus M.A.M.E. shite
27 int cpu_scalebyfcount(int f) { return f; }
28 void timer_remove(void * foo) { printf("STUB: timer_remove()\n"); }
29 void * timer_set(int foo, int bar, void (* baz)(int)) { printf("STUB: timer_set()\n"); return 0; }
39 ** Shifts below are subject to change if sampling frequency changes...
41 #define FREQ_SH 16 /* 16.16 fixed point for frequency calculations */
42 #define LFO_SH 24 /* 8.24 fixed point for LFO frequency calculations */
43 #define ENV_SH 16 /* 16.16 fixed point for envelope calculations */
44 #define TIMER_SH 16 /* 16.16 fixed point for timers calculations */
47 #define ENV_RES ((int)1<<ENV_BITS)
48 #define ENV_STEP (96.0/ENV_RES)
49 #define MAX_VOLUME_INDEX ((ENV_RES-1)<<ENV_SH)
50 #define MIN_VOLUME_INDEX (0)
51 #define VOLUME_OFF (ENV_RES<<ENV_SH)
54 #define SIN_LEN ((int)1<<SIN_BITS)
55 #define SIN_MASK (SIN_LEN-1)
57 #define FINAL_SH8 7 /*this shift is applied to final output of all channels to get 8-bit sample */
58 #define FINAL_SH16 0 /*this shift is applied to final output of all channels to get 16-bit sample*/
60 static uint8_t FEED[8] = {0,7,6,5,4,3,2,1}; /*shifts (divider) for output of op.0 which feeds into itself*/
62 #define TL_TAB_LEN (2*(ENV_RES + ENV_RES + ENV_RES + SIN_LEN))
63 static signed int * TL_TAB = NULL;
65 * Offset in this table is calculated as:
68 * TL- main offset (Total attenuation Level), range 0 to 1023 (0-96 dB)
70 * current envelope value of the operator, range 0 to 1023 (0-96 dB)
72 * Amplitude Modulation from LFO, range 0 to 1023 (0-96dB)
74 * Sin Wave Offset from sin_tab, range 0 to about 56 dB only, but lets
75 * simplify things and assume sin could be 96 dB, range 0 to 1023
77 * Length of this table is doubled because we have two separate parts
78 * for positive and negative halves of sin wave (above and below X axis).
81 static signed int * sin_tab[SIN_LEN]; /* sin waveform table in decibel scale */
84 /*tables below are defined for usage by LFO */
85 signed int PMsaw [SIN_LEN]; /*saw waveform table PM */
86 signed int PMsquare [SIN_LEN]; /*square waveform table PM */
87 signed int PMtriangle[SIN_LEN]; /*triangle waveform table PM */
88 signed int PMnoise [SIN_LEN]; /*noise waveform table PM */
90 uint16_t AMsaw [SIN_LEN]; /*saw waveform table AM */
91 uint16_t AMsquare [SIN_LEN]; /*square waveform table AM */
92 uint16_t AMtriangle[SIN_LEN]; /*triangle waveform table AM */
93 uint16_t AMnoise [SIN_LEN]; /*noise waveform table AM */
96 static int YM2151_CLOCK = 1; /* this will be passed from 2151intf.c */
97 static int YM2151_SAMPFREQ = 1; /* this will be passed from 2151intf.c */
98 //static uint8_t sample_16bit; /* 1 -> 16 bit sample, 0 -> 8 bit */
100 static int YMBufSize; /* size of sound buffer, in samples */
101 static int YMNumChips; /* total # of YM's emulated */
103 static int TimerA[1024];
104 static int TimerB[256];
106 /* ASG 980324: added */
107 static double TimerATime[1024];
108 static double TimerBTime[256];
110 static YM2151 * YMPSG = NULL; /* array of YM's */
112 signed int * BuffTemp = NULL; /*temporary buffer for speedup purposes*/
114 static void (* envelope_calc[5])(OscilRec *);
115 static void (* register_writes[256])(uint8_t, uint8_t, uint8_t);
117 //save output as raw 16-bit sample - just in case you would like to listen to it offline ;-)
118 //#define SAVE_SAMPLE
119 //#define SAVE_SEPARATE_CHANNELS
122 #ifdef SAVE_SEPARATE_CHANNELS
133 int PMTab[8]; /*8 channels */
134 /* this table is used for PM setup of LFO */
136 int AMTab[8]; /*8 channels */
137 /* this table is used for AM setup of LFO */
139 static int decib45[16];
140 /*decibel table to convert from D1L values to index in lookup table*/
142 static int attack_curve[ENV_RES];
144 unsigned int divia[64]; //Attack dividers
145 unsigned int divid[64]; //Decay dividers
146 static unsigned int A_DELTAS[64+31]; //Attack deltas (64 keycodes + 31 RKS's = 95)
147 static unsigned int D_DELTAS[64+31]; //Decay deltas (64 keycodes + 31 RKS's = 95)
149 float DT1Tab[32][4]={ /* 8 octaves * 4 key codes, 4 DT1 values */
151 * Table defines offset in Hertz from base frequency depending on KC and DT1
152 * User's Manual page 21
154 /*OCT NOTE DT1=0 DT1=1 DT1=2 DT1=3*/
155 /* 0 0*/{0, 0, 0.053, 0.107},
156 /* 0 1*/{0, 0, 0.053, 0.107},
157 /* 0 2*/{0, 0, 0.053, 0.107},
158 /* 0 3*/{0, 0, 0.053, 0.107},
159 /* 1 0*/{0, 0.053, 0.107, 0.107},
160 /* 1 1*/{0, 0.053, 0.107, 0.160},
161 /* 1 2*/{0, 0.053, 0.107, 0.160},
162 /* 1 3*/{0, 0.053, 0.107, 0.160},
163 /* 2 0*/{0, 0.053, 0.107, 0.213},
164 /* 2 1*/{0, 0.053, 0.160, 0.213},
165 /* 2 2*/{0, 0.053, 0.160, 0.213},
166 /* 2 3*/{0, 0.053, 0.160, 0.267},
167 /* 3 0*/{0, 0.107, 0.213, 0.267},
168 /* 3 1*/{0, 0.107, 0.213, 0.320},
169 /* 3 2*/{0, 0.107, 0.213, 0.320},
170 /* 3 3*/{0, 0.107, 0.267, 0.373},
171 /* 4 0*/{0, 0.107, 0.267, 0.427},
172 /* 4 1*/{0, 0.160, 0.320, 0.427},
173 /* 4 2*/{0, 0.160, 0.320, 0.480},
174 /* 4 3*/{0, 0.160, 0.373, 0.533},
175 /* 5 0*/{0, 0.213, 0.427, 0.587},
176 /* 5 1*/{0, 0.213, 0.427, 0.640},
177 /* 5 2*/{0, 0.213, 0.480, 0.693},
178 /* 5 3*/{0, 0.267, 0.533, 0.747},
179 /* 6 0*/{0, 0.267, 0.587, 0.853},
180 /* 6 1*/{0, 0.320, 0.640, 0.907},
181 /* 6 2*/{0, 0.320, 0.693, 1.013},
182 /* 6 3*/{0, 0.373, 0.747, 1.067},
183 /* 7 0*/{0, 0.427, 0.853, 1.173},
184 /* 7 1*/{0, 0.427, 0.907, 1.173},
185 /* 7 2*/{0, 0.480, 1.013, 1.173},
186 /* 7 3*/{0, 0.533, 1.067, 1.173}
189 static uint16_t DT2Tab[4]={ /* 4 DT2 values */
191 * DT2 defines offset in cents from base note
193 * The table below defines offset in deltas table...
194 * User's Manual page 22
195 * Values below were calculated using formula: value = orig.val / 1.5625
197 * DT2=0 DT2=1 DT2=2 DT2=3
203 static uint16_t KC_TO_INDEX[16*8]; /*16 note codes * 8 octaves */
204 /*translate key code KC (OCT2 OCT1 OCT0 N3 N2 N1 N0) into index in deltas table*/
206 static signed int DT1deltas[32][8];
208 static signed int deltas[9*12*64];/*9 octaves, 12 semitones, 64 'cents' */
209 /*deltas in sintable (fixed point) to get the closest frequency possible */
210 /*there're 9 octaves because of DT2 (max 950 cents over base frequency) */
212 static signed int LFOdeltas[256]; /*frequency deltas for LFO*/
220 for(i=0; i<SIN_LEN; i++)
222 m = sin(2 * PI * i / SIN_LEN); /*count sin value*/
224 if ((m < 0.0001) && (m > -0.0001)) /*is m very close to zero ?*/
230 m = 20 * log10(1.0 / m); /* and how many decibels is it? */
235 m = 20 * log10(-1.0 / m); /* and how many decibels is it? */
236 m = (m / ENV_STEP) + TL_TAB_LEN / 2;
240 sin_tab[i] = &TL_TAB[(unsigned int)m]; /**/
241 //if (errorlog) fprintf(errorlog,"sin %i = %i\n",i,sin_tab[i] );
244 for(x=0; x<TL_TAB_LEN/2; x++)
248 if ((x * ENV_STEP) < 6.0) /*have we passed 6 dB*/
249 { /*nope, we didn't */
250 m = ((1 << 12) - 1) / pow(10, x * ENV_STEP / 20);
254 /*if yes, we simplify things (and the real chip */
255 /*probably does it also) and assume that - 6dB */
256 /*halves the voltage (it _nearly_ does in fact) */
257 m = TL_TAB[(int)((float)x - (6.0 / ENV_STEP))] / 2;
266 TL_TAB[x + TL_TAB_LEN / 2] = -m;
267 //if (errorlog) fprintf(errorlog,"tl %04i =%08x\n",x,TL_TAB[x]);
270 /* create attack curve */
271 for(i=0; i<ENV_RES; i++)
273 m = (ENV_RES - 1) / pow(10, i * (48.0 / ENV_RES) / 20);
274 x = m * (1 << ENV_SH);
275 attack_curve[ENV_RES - 1 - i] = x;
276 //if (errorlog) fprintf(errorlog,"attack [%04x] = %08x Volt=%08x\n", ENV_RES-1-i, x/(1<<ENV_SH), TL_TAB[x/(1<<ENV_SH)] );
281 i = (x < 15 ? x : x + 16) * (3.0 / ENV_STEP); /*every 3 dB except for ALL '1' = 45dB+48dB*/
284 //if (errorlog) fprintf(errorlog,"decib45[%04x]=%08x\n",x,i );
288 #ifdef SAVE_SEPARATE_CHANNELS
289 sample1=fopen("samp.raw","wb");
290 sample2=fopen("samp2.raw","wb");
291 sample3=fopen("samp3.raw","wb");
292 sample4=fopen("samp4.raw","wb");
293 sample5=fopen("samp5.raw","wb");
294 sample6=fopen("samp6.raw","wb");
296 samplesum=fopen("sampsum.raw","wb");
306 float scaler; /* formula below is true for chip clock=3579545 */
307 /* so we need to scale its output accordingly to the chip clock */
309 /*this loop calculates Hertz values for notes from c#0 up to c-8*/
310 /*including 64 'cents' (100/64 which is 1.5625 of real cent) for each semitone*/
312 scaler = (float)YM2151_CLOCK / 3579545.0;
315 mult = (long int)1 << FREQ_SH;
317 for(i=0; i<1*12*64; i++)
319 pom = scaler * 6.875 * pow(2, ((i + 4 * 64) * 1.5625 / 1200.0)); /*13.75Hz is note A 12semitones below A-0, so C#0 is 4 semitones above then*/
320 /*calculate phase increment for above precounted Hertz value*/
321 pom2 = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
323 deltas[i + oct * 4] = pom2 * 16; /*oct 4 - center*/
324 deltas[i + oct * 5] = deltas[oct * 4 + i] << 1; //oct 5
325 deltas[i + oct * 6] = deltas[oct * 4 + i] << 2; //oct 6
326 deltas[i + oct * 7] = deltas[oct * 4 + i] << 3; //oct 7
327 deltas[i + oct * 8] = deltas[oct * 4 + i] << 4; //oct 8
329 deltas[i + oct * 3] = deltas[oct * 4 + i] >> 1; //oct 3
330 deltas[i + oct * 2] = deltas[oct * 4 + i] >> 2; //oct 2
331 deltas[i + oct * 1] = deltas[oct * 4 + i] >> 3; //oct 1
332 deltas[i + oct * 0] = deltas[oct * 4 + i] >> 4; //oct 0
334 //if (errorlog) fprintf(errorlog,"deltas[%04i] = %08x\n",i,deltas[i]);
341 pom = scaler * DT1Tab[i][j];
342 //calculate phase increment for above precounted Hertz value
343 DT1deltas[i][j] = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
344 DT1deltas[i][j + 4] = -DT1deltas[i][j];
348 mult = (long int)1 << LFO_SH;
349 m = (float)YM2151_CLOCK;
354 pom = scaler * fabs((m / 65536 / (1 << (i / 16))) - (m / 65536 / 32 / (1 << (i / 16)) * (j + 1)));
356 /*calculate phase increment for above precounted Hertz value*/
357 pom2 = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
358 LFOdeltas[0xFF - i] = pom2;
359 //if (errorlog) fprintf(errorlog, "LFO[%02x] = %08x\n",0xff-i, LFOdeltas[0xff-i]);
362 /* calculate KC to index table */
364 for(i=0; i<16*8; i++)
366 KC_TO_INDEX[i] = (i >> 4) * 12 * 64 + j * 64 ;
369 j++; /* change note code */
372 j = 0; /* new octave */
374 //if (errorlog) fprintf(errorlog,"NOTE[%i] = %i\n",i,KC_TO_INDEX[i]);
377 /* precalculate envelope times */
380 pom = (16 << (i >> 2)) + (4 << (i >> 2)) * (i & 0x03);
386 pom = 524288; //const
393 pom = ((128+64+32)<<(i>>2))+((32+16+8)<<(i>>2))*(i&0x03);
395 if ((i>>2)==0) pom=1; //infinity
400 pom = 153293300; //zero attack time
402 pom = 6422528; //const attack time
408 mult = (long int)1 << ENV_SH;
415 pom = (scaler * ENV_RES * mult) / ((float)YM2151_SAMPFREQ * ((float)YM2151_CLOCK / 1000.0 / (float)divid[i]));
416 //if (errorlog) fprintf(errorlog,"i=%03i div=%i time=%f delta=%f\n",i,divid[i],
417 // (float)YM2151_CLOCK/1000.0/(float)divid[i], pom );
426 pom = (scaler * ENV_RES * mult) / ((float)YM2151_SAMPFREQ * ((float)YM2151_CLOCK / 1000.0 / (float)divia[i]));
428 //if (errorlog) fprintf(errorlog,"i=%03i div=%i time=%f delta=%f\n",i,divia[i],
429 // (float)YM2151_CLOCK/1000.0/(float)divia[i], pom );
433 // This is only for speedup purposes -> to avoid testing if (keycode+RKS is
437 D_DELTAS[64 + i] = D_DELTAS[63];
438 A_DELTAS[64 + i] = A_DELTAS[63];
441 /* precalculate timers deltas */
442 /* User's Manual pages 15,16 */
443 mult = (int)1 << TIMER_SH;
445 for(i=0; i<1024; i++)
447 /* ASG 980324: changed to compute both TimerA and TimerATime */
448 pom = (64.0 * (1024.0 - i) / YM2151_CLOCK);
450 TimerA[i] = pom * YM2151_SAMPFREQ * mult; /*number of samples that timer period should last (fixed point) */
455 /* ASG 980324: changed to compute both TimerB and TimerBTime */
456 pom = (1024.0 * (256.0 - i) / YM2151_CLOCK);
458 TimerB[i] = pom * YM2151_SAMPFREQ * mult; /*number of samples that timer period should last (fixed point) */
463 void envelope_attack(OscilRec * op)
465 if ((op->attack_volume -= op->delta_AR) < MIN_VOLUME_INDEX) //is volume index min already ?
467 op->volume = MIN_VOLUME_INDEX;
471 op->volume = attack_curve[op->attack_volume>>ENV_SH];
475 void envelope_decay(OscilRec * op)
477 if ((op->volume += op->delta_D1R) > op->D1L)
479 //op->volume = op->D1L;
485 void envelope_sustain(OscilRec * op)
487 if ((op->volume += op->delta_D2R) > MAX_VOLUME_INDEX)
490 op->volume = VOLUME_OFF;
495 void envelope_release(OscilRec * op)
497 if ((op->volume += op->delta_RR) > MAX_VOLUME_INDEX)
500 op->volume = VOLUME_OFF;
505 void envelope_nothing(OscilRec *op)
510 inline void envelope_KOFF(OscilRec * op)
512 op->state = 3; /*release*/
516 inline void envelope_KON(OscilRec * op)
518 /*this is to remove the gap time if TL>0*/
519 op->volume = VOLUME_OFF; //(ENV_RES - op->TL)<<ENV_SH; /*** <- SURE ABOUT IT ? No, but let's give it a try...*/
520 op->attack_volume = op->volume;
522 op->state = 0; /*KEY ON = attack*/
523 op->OscilFB = 0; /*Clear feedback after key on */
527 void refresh_chip(YM2151 * PSG)
529 uint16_t kc_index_oscil, kc_index_channel, mul;
534 for(chan=7; chan>=0; chan--)
537 kc_index_channel = KC_TO_INDEX[kc] + PSG->KF[chan];
540 for(k=24; k>=0; k-=8)
543 osc = &PSG->Oscils[op];
546 v = (PSG->Regs[YM_DT2_D2R_BASE + op] >> 6) & 0x03; //DT2 value
547 kc_index_oscil = kc_index_channel + DT2Tab[v]; //DT2 offset
548 v = PSG->Regs[YM_DT1_MUL_BASE + op];
549 mul = (v & 0x0F) << 1;
552 osc->freq = deltas[kc_index_oscil] * mul;
554 osc->freq = deltas[kc_index_oscil];
556 osc->freq += DT1deltas[kc][(v >> 4) & 0x07]; //DT1 value
559 /*calc envelopes begin*/
560 v = kc >> PSG->KS[op];
561 osc->delta_AR = A_DELTAS[ osc->AR + v]; /* 2*RR + RKS =max 95*/
562 osc->delta_D1R = D_DELTAS[osc->D1R + v]; /* 2*RR + RKS =max 95*/
563 osc->delta_D2R = D_DELTAS[osc->D2R + v]; /* 2*RR + RKS =max 95*/
564 osc->delta_RR = D_DELTAS[ osc->RR + v]; /* 2*RR + RKS =max 95*/
565 /*calc envelopes end*/
571 void write_YM_NON_EMULATED(uint8_t n, uint8_t r, uint8_t v)
574 fprintf(errorlog, "Write to non emulated register %02x value %02x\n", r, v);
578 void write_YM_KON(uint8_t n, uint8_t r, uint8_t v)
581 YM2151 * PSG = &(YMPSG[n]);
586 envelope_KON(&PSG->Oscils[chan]);
588 envelope_KOFF(&PSG->Oscils[chan]);
591 envelope_KON(&PSG->Oscils[chan + 16]);
593 envelope_KOFF(&PSG->Oscils[chan + 16]);
596 envelope_KON(&PSG->Oscils[chan + 8]);
598 envelope_KOFF(&PSG->Oscils[chan + 8]);
601 envelope_KON(&PSG->Oscils[chan + 24]);
603 envelope_KOFF(&PSG->Oscils[chan + 24]);
607 void write_YM_CLOCKA1(uint8_t n, uint8_t r, uint8_t v)
609 YMPSG[n].Regs[r] = v;
613 void write_YM_CLOCKA2(uint8_t n, uint8_t r, uint8_t v)
615 YMPSG[n].Regs[r] = v & 0x03;
619 void write_YM_CLOCKB(uint8_t n, uint8_t r, uint8_t v)
621 YMPSG[n].Regs[r] = v;
625 static void timer_callback_a(int n)
627 YM2151 * PSG = &YMPSG[n];
628 // YM2151UpdateOne(n, cpu_scalebyfcount(YMBufSize));
639 static void timer_callback_b(int n)
641 YM2151 * PSG = &YMPSG[n];
642 // YM2151UpdateOne(n, cpu_scalebyfcount(YMBufSize));
653 void write_YM_CLOCKSET(uint8_t n, uint8_t r, uint8_t v)
655 YM2151 * PSG = &(YMPSG[n]);
659 // if (errorlog) fprintf(errorlog,"CSM= %01x FRESET=%02x, IRQEN=%02x, LOAD=%02x\n",v>>7,(v>>4)&0x03,(v>>2)&0x03,v&0x03 );
664 /* ASG 980324: remove the timers if they exist */
666 timer_remove(PSG->TimATimer);
669 timer_remove(PSG->TimBTimer);
674 if (v & 0x01) //LOAD A
677 PSG->TimAVal = TimerA[(PSG->Regs[YM_CLOCKA1] << 2) | PSG->Regs[YM_CLOCKA2]];
678 /* ASG 980324: added a real timer if we have a handler */
681 PSG->TimATimer = timer_set(TimerATime[(PSG->Regs[YM_CLOCKA1] << 2) | PSG->Regs[YM_CLOCKA2]], n, timer_callback_a);
686 if (v & 0x02) //load B
689 PSG->TimBVal = TimerB[PSG->Regs[YM_CLOCKB]];
691 /* ASG 980324: added a real timer if we have a handler */
693 PSG->TimBTimer = timer_set (TimerBTime[PSG->Regs[YM_CLOCKB]], n, timer_callback_b);
698 if (v & 0x04) //IRQEN A
701 if (v & 0x08) //IRQEN B
704 if (v & 0x10) //FRESET A
709 if (v & 0x20) //FRESET B
716 void write_YM_CT1_CT2_W(uint8_t n, uint8_t r, uint8_t v)
718 YMPSG[n].Regs[r] = v;
722 void write_YM_CONNECT_BASE(uint8_t n, uint8_t r, uint8_t v)
724 // NOTE: L/R Channel enables are ignored! This emu is mono!
725 YM2151 * PSG = &(YMPSG[n]);
728 uint8_t chan = r - YM_CONNECT_BASE;
730 PSG->ConnectTab[chan] = v & 7; /*connection number*/
731 PSG->FeedBack[chan] = FEED[(v >> 3) & 7];
735 void write_YM_KC_BASE(uint8_t n, uint8_t r, uint8_t v)
737 YMPSG[n].KC[r - YM_KC_BASE] = v;
738 //freq_calc(chan,PSG);
742 void write_YM_KF_BASE(uint8_t n, uint8_t r, uint8_t v)
744 YMPSG[n].KF[r - YM_KF_BASE] = v >> 2;
745 //freq_calc(chan,PSG);
749 void write_YM_PMS_AMS_BASE(uint8_t n, uint8_t r, uint8_t v)
752 YM2151 * PSG = &(YMPSG[n]);
754 uint8_t chan = r - YM_PMS_AMS_BASE;
756 PMTab[chan] = v >> 4; //PMS;
758 // if (i && errorlog)
759 // fprintf(errorlog,"PMS CHN %02x =%02x\n", chan, i);
761 AMTab[chan] = v & 0x03; //AMS;
763 // if (i && errorlog)
764 // fprintf(errorlog,"AMS CHN %02x =%02x\n", chan, i);
769 void write_YM_DT1_MUL_BASE(uint8_t n, uint8_t r, uint8_t v)
771 YMPSG[n].Regs[r] = v;
772 //freq_calc(chan,PSG);
776 void write_YM_TL_BASE(uint8_t n, uint8_t r, uint8_t v)
779 YMPSG[n].Oscils[r - YM_TL_BASE].TL = v << (ENV_BITS - 7); /*7bit TL*/
783 void write_YM_KS_AR_BASE(uint8_t n, uint8_t r, uint8_t v)
788 op = r - YM_KS_AR_BASE;
791 PSG->KS[op] = 3 - (v >> 6);
792 PSG->Oscils[op].AR = (v & 0x1F) << 1;
796 void write_YM_AMS_D1R_BASE(uint8_t n, uint8_t r, uint8_t v)
798 uint8_t op = r - YM_AMS_D1R_BASE;
800 if ((v & 0x80) && errorlog)
801 fprintf(errorlog,"AMS ON oper%02x\n", op);
803 //HERE something to do with AMS;
805 YMPSG[n].Oscils[op].D1R = (v & 0x1F) << 1;
809 void write_YM_DT2_D2R_BASE(uint8_t n, uint8_t r, uint8_t v)
811 YM2151 * PSG = &(YMPSG[n]);
812 OscilRec * osc = &PSG->Oscils[r - YM_DT2_D2R_BASE];
815 osc->D2R = (v & 0x1F) << 1;
816 //freq_calc(chan,PSG);
820 void write_YM_D1L_RR_BASE(uint8_t n, uint8_t r, uint8_t v)
822 OscilRec * osc = &YMPSG[n].Oscils[r - YM_D1L_RR_BASE];
824 osc->D1L = decib45[(v >> 4) & 0x0F];
825 osc->RR = ((v & 0x0F) << 2) | 0x02;
830 ** Initialize YM2151 emulator(s).
832 ** 'num' is the number of virtual YM2151's to allocate
833 ** 'clock' is the chip clock
834 ** 'rate' is sampling rate and 'bufsiz' is the size of the
835 ** buffer that should be updated at each interval
837 int YMInit(int num, int clock, int rate, int sample_bits, int bufsiz)//, SAMPLE ** buffer)
842 return (-1); /* duplicate init. */
845 YM2151_SAMPFREQ = rate;
848 if (sample_bits == 16)
854 YM2151_CLOCK = clock;
857 envelope_calc[0] = envelope_attack;
858 envelope_calc[1] = envelope_decay;
859 envelope_calc[2] = envelope_sustain;
860 envelope_calc[3] = envelope_release;
861 envelope_calc[4] = envelope_nothing;
864 register_writes[i] = write_YM_NON_EMULATED;
866 register_writes[YM_KON] = write_YM_KON;
867 register_writes[YM_CLOCKA1] = write_YM_CLOCKA1;
868 register_writes[YM_CLOCKA2] = write_YM_CLOCKA2;
869 register_writes[YM_CLOCKB] = write_YM_CLOCKB;
870 register_writes[YM_CLOCKSET] = write_YM_CLOCKSET;
871 register_writes[YM_CT1_CT2_W] = write_YM_CT1_CT2_W;
873 for(i=YM_CONNECT_BASE; i<YM_CONNECT_BASE+8; i++)
874 register_writes[i] = write_YM_CONNECT_BASE;
876 for(i=YM_KC_BASE; i<YM_KC_BASE+8; i++)
877 register_writes[i] = write_YM_KC_BASE;
879 for(i=YM_KF_BASE; i<YM_KF_BASE+8; i++)
880 register_writes[i] = write_YM_KF_BASE;
882 for(i=YM_PMS_AMS_BASE; i<YM_PMS_AMS_BASE+8; i++)
883 register_writes[i] = write_YM_PMS_AMS_BASE;
885 for(i=YM_DT1_MUL_BASE; i<YM_DT1_MUL_BASE+32; i++)
886 register_writes[i] = write_YM_DT1_MUL_BASE;
888 for(i=YM_TL_BASE; i<YM_TL_BASE+32; i++)
889 register_writes[i] = write_YM_TL_BASE;
891 for(i=YM_KS_AR_BASE; i<YM_KS_AR_BASE+32; i++)
892 register_writes[i] = write_YM_KS_AR_BASE;
894 for(i=YM_AMS_D1R_BASE; i<YM_AMS_D1R_BASE+32; i++)
895 register_writes[i] = write_YM_AMS_D1R_BASE;
897 for(i=YM_DT2_D2R_BASE; i<YM_DT2_D2R_BASE+32; i++)
898 register_writes[i] = write_YM_DT2_D2R_BASE;
900 for(i=YM_D1L_RR_BASE; i<YM_D1L_RR_BASE+32; i++)
901 register_writes[i] = write_YM_D1L_RR_BASE;
903 YMPSG = (YM2151 *)malloc(sizeof(YM2151) * YMNumChips);
908 TL_TAB = (signed int *)malloc(sizeof(signed int) * TL_TAB_LEN);
913 // BuffTemp = (signed int *)malloc(sizeof(signed int) * YMBufSize);
914 // 16K ought to be enough for anybody
915 BuffTemp = (signed int *)malloc(sizeof(signed int) * 16384);
917 if (BuffTemp == NULL)
923 for(i=0; i<YMNumChips; i++)
925 YMPSG[i].Buf = 0;//buffer[i];
954 YM2151_SAMPFREQ = YMBufSize = 0;
957 #ifdef SAVE_SEPARATE_CHANNELS
970 /* write a register on YM2151 chip number 'n' */
971 void YMWriteReg(int n, int r, int v)
973 register_writes[(uint8_t)r]((uint8_t)n, (uint8_t)r, (uint8_t)v);
977 uint8_t YMReadReg(uint8_t n)
979 return YMPSG[n].TimIRQ;
984 ** reset all chip registers.
986 void YMResetChip(int num)
989 YM2151 * PSG = &(YMPSG[num]);
991 memset(PSG->Buf, '\0', YMBufSize);
993 /* ASG 980324 -- reset the timers before writing to the registers */
997 /* initialize hardware registers */
1003 memset(&PSG->Oscils[i], '\0', sizeof(OscilRec));
1004 PSG->Oscils[i].volume = VOLUME_OFF;
1005 PSG->Oscils[i].state = 4; //envelope off
1010 PSG->ConnectTab[i] = 0;
1011 PSG->FeedBack[i] = 0;
1022 static inline signed int op_calc(OscilRec * OP, signed int pm)
1024 return sin_tab[(((OP->phase += OP->freq) >> FREQ_SH) + (pm)) & SIN_MASK]
1025 [OP->TL + (OP->volume >> ENV_SH)];
1029 //void YM2151UpdateOne(int num, int endp)
1030 void YM2151UpdateOne(void * BUF, int endp)
1032 // YM2151 * PSG = &(YMPSG[num]);
1033 YM2151 * PSG = &(YMPSG[0]);
1036 signed int * PSGBUF;
1037 OscilRec * OP0, * OP1, * OP2, * OP3;
1040 #ifdef SAVE_SEPARATE_CHANNELS
1046 //calculate timers...
1049 PSG->TimAVal -= ((endp - PSG->bufp) << TIMER_SH);
1051 if (PSG->TimAVal <= 0)
1055 /* ASG 980324 - handled by real timers now
1056 if (PSG->handler !=0) PSG->handler();*/
1062 PSG->TimBVal -= ((endp - PSG->bufp) << TIMER_SH);
1064 if (PSG->TimBVal <= 0)
1068 /* ASG 980324 - handled by real timers now
1069 if (PSG->handler !=0) PSG->handler();*/
1073 OP0 = &PSG->Oscils[0 ];
1074 OP1 = &PSG->Oscils[0 + 8];
1075 OP2 = &PSG->Oscils[0 + 16];
1076 OP3 = &PSG->Oscils[0 + 24];
1078 for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1081 envelope_calc[OP0->state](OP0);
1082 envelope_calc[OP1->state](OP1);
1083 envelope_calc[OP2->state](OP2);
1084 envelope_calc[OP3->state](OP3);
1086 wy = op_calc(OP0, OP0->OscilFB);
1088 if (PSG->FeedBack[0])
1089 OP0->OscilFB = wy >> PSG->FeedBack[0];
1093 switch(PSG->ConnectTab[0])
1095 case 0: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, wy))); break;
1096 case 1: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, 0) + wy)); break;
1097 case 2: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, 0)) + wy); break;
1098 case 3: *(PSGBUF) = op_calc(OP3, op_calc(OP2, wy) + op_calc(OP1, 0)); break;
1099 case 4: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP3, op_calc(OP1, 0)); break;
1100 case 5: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP1, wy) + op_calc(OP3, wy); break;
1101 case 6: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
1102 default: *(PSGBUF) = wy + op_calc(OP2, 0) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
1104 #ifdef SAVE_SEPARATE_CHANNELS
1105 fputc((uint16_t)(*PSGBUF) & 0xFF, sample1);
1106 fputc(((uint16_t)(*PSGBUF) >> 8) & 0xFF, sample1);
1111 OP0 = &PSG->Oscils[1 ];
1112 OP1 = &PSG->Oscils[1 + 8];
1113 OP2 = &PSG->Oscils[1 + 16];
1114 OP3 = &PSG->Oscils[1 + 24];
1116 for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1118 envelope_calc[OP0->state](OP0);
1119 envelope_calc[OP1->state](OP1);
1120 envelope_calc[OP2->state](OP2);
1121 envelope_calc[OP3->state](OP3);
1123 wy = op_calc(OP0, OP0->OscilFB);
1125 if (PSG->FeedBack[1])
1126 OP0->OscilFB = wy >> PSG->FeedBack[1];
1130 #ifdef SAVE_SEPARATE_CHANNELS
1133 switch(PSG->ConnectTab[1])
1135 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1136 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1137 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1138 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1139 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1140 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1141 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1142 default: *(PSGBUF) += wy + op_calc(OP2, 0) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
1145 #ifdef SAVE_SEPARATE_CHANNELS
1146 fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample2);
1147 fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample2);
1152 OP0 = &PSG->Oscils[2 ];
1153 OP1 = &PSG->Oscils[2 + 8];
1154 OP2 = &PSG->Oscils[2 + 16];
1155 OP3 = &PSG->Oscils[2 + 24];
1157 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1159 envelope_calc[OP0->state](OP0);
1160 envelope_calc[OP1->state](OP1);
1161 envelope_calc[OP2->state](OP2);
1162 envelope_calc[OP3->state](OP3);
1164 wy = op_calc(OP0, OP0->OscilFB);
1165 if (PSG->FeedBack[2])
1166 OP0->OscilFB = wy >> PSG->FeedBack[2];
1170 #ifdef SAVE_SEPARATE_CHANNELS
1173 switch(PSG->ConnectTab[2])
1175 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1176 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1177 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1178 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1179 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1180 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1181 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1182 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1184 #ifdef SAVE_SEPARATE_CHANNELS
1185 fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample3);
1186 fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample3);
1191 OP0 = &PSG->Oscils[3 ];
1192 OP1 = &PSG->Oscils[3 + 8];
1193 OP2 = &PSG->Oscils[3 + 16];
1194 OP3 = &PSG->Oscils[3 + 24];
1196 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1198 envelope_calc[OP0->state](OP0);
1199 envelope_calc[OP1->state](OP1);
1200 envelope_calc[OP2->state](OP2);
1201 envelope_calc[OP3->state](OP3);
1203 wy = op_calc(OP0, OP0->OscilFB);
1204 if (PSG->FeedBack[3])
1205 OP0->OscilFB = wy >> PSG->FeedBack[3];
1209 #ifdef SAVE_SEPARATE_CHANNELS
1212 switch(PSG->ConnectTab[3])
1214 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1215 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1216 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1217 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1218 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1219 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1220 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1221 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1223 #ifdef SAVE_SEPARATE_CHANNELS
1224 fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample4);
1225 fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample4);
1230 OP0 = &PSG->Oscils[4 ];
1231 OP1 = &PSG->Oscils[4 + 8];
1232 OP2 = &PSG->Oscils[4 + 16];
1233 OP3 = &PSG->Oscils[4 + 24];
1235 for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1237 envelope_calc[OP0->state](OP0);
1238 envelope_calc[OP1->state](OP1);
1239 envelope_calc[OP2->state](OP2);
1240 envelope_calc[OP3->state](OP3);
1242 wy = op_calc(OP0, OP0->OscilFB);
1244 if (PSG->FeedBack[4])
1245 OP0->OscilFB = wy >> PSG->FeedBack[4];
1249 #ifdef SAVE_SEPARATE_CHANNELS
1253 switch(PSG->ConnectTab[4])
1255 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1256 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1257 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1258 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1259 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1260 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1261 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1262 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1265 #ifdef SAVE_SEPARATE_CHANNELS
1266 fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample5);
1267 fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample5);
1272 OP0 = &PSG->Oscils[5 ];
1273 OP1 = &PSG->Oscils[5 + 8];
1274 OP2 = &PSG->Oscils[5 + 16];
1275 OP3 = &PSG->Oscils[5 + 24];
1277 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1279 envelope_calc[OP0->state](OP0);
1280 envelope_calc[OP1->state](OP1);
1281 envelope_calc[OP2->state](OP2);
1282 envelope_calc[OP3->state](OP3);
1284 wy = op_calc(OP0, OP0->OscilFB);
1285 if (PSG->FeedBack[5])
1286 OP0->OscilFB = wy >> PSG->FeedBack[5];
1290 #ifdef SAVE_SEPARATE_CHANNELS
1293 switch(PSG->ConnectTab[5])
1295 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1296 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1297 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1298 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1299 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1300 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1301 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1302 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1304 #ifdef SAVE_SEPARATE_CHANNELS
1305 fputc((uint16_t)((*PSGBUF)-pom)&0xff,sample6);
1306 fputc(((uint16_t)((*PSGBUF)-pom)>>8)&0xff,sample6);
1311 OP0 = &PSG->Oscils[6 ];
1312 OP1 = &PSG->Oscils[6 + 8];
1313 OP2 = &PSG->Oscils[6 + 16];
1314 OP3 = &PSG->Oscils[6 + 24];
1316 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1318 envelope_calc[OP0->state](OP0);
1319 envelope_calc[OP1->state](OP1);
1320 envelope_calc[OP2->state](OP2);
1321 envelope_calc[OP3->state](OP3);
1323 wy = op_calc(OP0, OP0->OscilFB);
1324 if (PSG->FeedBack[6])
1325 OP0->OscilFB = wy >> PSG->FeedBack[6];
1329 switch(PSG->ConnectTab[6])
1331 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1332 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1333 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1334 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1335 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1336 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1337 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1338 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1343 OP0 = &PSG->Oscils[7 ];
1344 OP1 = &PSG->Oscils[7 + 8];
1345 OP2 = &PSG->Oscils[7 + 16];
1346 OP3 = &PSG->Oscils[7 + 24];
1348 for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1350 envelope_calc[OP0->state](OP0);
1351 envelope_calc[OP1->state](OP1);
1352 envelope_calc[OP2->state](OP2);
1353 envelope_calc[OP3->state](OP3);
1355 wy = op_calc(OP0, OP0->OscilFB);
1357 if (PSG->FeedBack[7])
1358 OP0->OscilFB = wy >> PSG->FeedBack[7];
1362 switch(PSG->ConnectTab[7])
1364 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) ); break;
1365 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1366 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1367 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) ); break;
1368 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0)); break;
1369 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1370 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0); break;
1371 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1376 PSGBUF = &BuffTemp[PSG->bufp];
1378 for(i=PSG->bufp; i<endp; i++)
1383 fputc((uint16_t)(-k) & 0xFF, samplesum);
1384 fputc(((uint16_t)(-k) >> 8) & 0xFF, samplesum);
1387 // if (sample_16bit)
1390 k >>= FINAL_SH16; //AUDIO_CONV
1395 else if (k < -32768)
1398 ((uint16_t *)BUF)[i] = (uint16_t)k;
1404 k >>= FINAL_SH8; //AUDIO_CONV
1411 ((uint8_t *)BUF)[i] = (uint8_t)k;
1421 ** called to update all chips
1423 void YM2151Update(void)
1426 for(i=0; i<YMNumChips; i++)
1428 if (YMPSG[i].bufp < YMBufSize)
1429 ;// YM2151UpdateOne(i, YMBufSize);
1437 ** return the buffer into which YM2151Update() has just written it's sample
1440 SAMPLE * YMBuffer(int n)
1442 return YMPSG[n].Buf;
1446 void YMSetIrqHandler(int n, void(* handler)(void))
1448 YMPSG[n].handler = handler;