]> Shamusworld >> Repos - thunder/blob - src/ym2151.cpp
29d7e992203774b39cef6f7d1727f327df79846a
[thunder] / src / ym2151.cpp
1 //
2 // Jarek Burczynski's YM2151 emulator
3 //
4 // Cleaned of most MAMEisms & cleaned up in general by James Hammons
5 // (this is mostly a placeholder until I write my own)
6 //
7
8 #include "ym2151.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <math.h>
14 #include <stdint.h>
15
16 // Missing shit (from M.A.M.E.)
17
18 #if 1
19 #define PI 3.1415629535897932338
20 static FILE * errorlog = 0;
21 //int cpu_scalebyfcount(int);
22 //void timer_remove(void *);
23 //void * timer_set(int, int, void (*)(int));
24
25 // Bogus M.A.M.E. shite
26 int cpu_scalebyfcount(int f) { return f; }
27 void timer_remove(void * foo) { printf("STUB: timer_remove()\n"); }
28 void * timer_set(int foo, int bar, void (* baz)(int)) { printf("STUB: timer_set()\n"); return 0; }
29
30 #endif
31
32 /*
33 **  some globals ...
34 */
35
36 /*
37 **  Shifts below are subject to change if sampling frequency changes...
38 */
39 #define FREQ_SH 16  /* 16.16 fixed point for frequency calculations     */
40 #define LFO_SH 24   /*  8.24 fixed point for LFO frequency calculations */
41 #define ENV_SH 16   /* 16.16 fixed point for envelope calculations      */
42 #define TIMER_SH 16 /* 16.16 fixed point for timers calculations        */
43
44 #define ENV_BITS 10
45 #define ENV_RES ((int)1<<ENV_BITS)
46 #define ENV_STEP (96.0/ENV_RES)
47 #define MAX_VOLUME_INDEX ((ENV_RES-1)<<ENV_SH)
48 #define MIN_VOLUME_INDEX (0)
49 #define VOLUME_OFF (ENV_RES<<ENV_SH)
50
51 #define SIN_BITS 10
52 #define SIN_LEN ((int)1<<SIN_BITS)
53 #define SIN_MASK (SIN_LEN-1)
54
55 #define FINAL_SH8 7   /*this shift is applied to final output of all channels to get 8-bit sample */
56 #define FINAL_SH16 0  /*this shift is applied to final output of all channels to get 16-bit sample*/
57
58 static uint8_t FEED[8] = {0,7,6,5,4,3,2,1}; /*shifts (divider) for output of op.0 which feeds into itself*/
59
60 #define TL_TAB_LEN (2*(ENV_RES + ENV_RES + ENV_RES + SIN_LEN))
61 static signed int * TL_TAB = NULL;
62 /*
63  *  Offset in this table is calculated as:
64  *
65  *  1st ENV_RES:
66  *     TL- main offset (Total attenuation Level), range 0 to 1023 (0-96 dB)
67  *  2nd ENV_RES:
68  *     current envelope value of the operator, range 0 to 1023 (0-96 dB)
69  *  3rd ENV_RES:
70  *     Amplitude Modulation from LFO, range 0 to 1023 (0-96dB)
71  *  4th SIN_LEN:
72  *     Sin Wave Offset from sin_tab, range 0 to about 56 dB only, but lets
73  *     simplify things and assume sin could be 96 dB, range 0 to 1023
74  *
75  *  Length of this table is doubled because we have two separate parts
76  *  for positive and negative halves of sin wave (above and below X axis).
77  */
78
79 static signed int * sin_tab[SIN_LEN];  /* sin waveform table in decibel scale */
80
81 #if 0
82 /*tables below are defined for usage by LFO */
83 signed int PMsaw     [SIN_LEN];   /*saw waveform table PM      */
84 signed int PMsquare  [SIN_LEN];   /*square waveform table PM   */
85 signed int PMtriangle[SIN_LEN];   /*triangle waveform table PM */
86 signed int PMnoise   [SIN_LEN];   /*noise waveform table PM    */
87
88 uint16_t AMsaw     [SIN_LEN];     /*saw waveform table AM      */
89 uint16_t AMsquare  [SIN_LEN];     /*square waveform table AM   */
90 uint16_t AMtriangle[SIN_LEN];     /*triangle waveform table AM */
91 uint16_t AMnoise   [SIN_LEN];     /*noise waveform table AM    */
92 #endif
93
94 static int YM2151_CLOCK = 1;            /* this will be passed from 2151intf.c */
95 static int YM2151_SAMPFREQ = 1;         /* this will be passed from 2151intf.c */
96 //static uint8_t sample_16bit;  /* 1 -> 16 bit sample, 0 -> 8 bit */
97
98 static int YMBufSize;           /* size of sound buffer, in samples */
99 static int YMNumChips;          /* total # of YM's emulated */
100
101 static int TimerA[1024];
102 static int TimerB[256];
103
104 /* ASG 980324: added */
105 static double TimerATime[1024];
106 static double TimerBTime[256];
107
108 static YM2151 * YMPSG = NULL;   /* array of YM's */
109
110 signed int * BuffTemp = NULL;   /*temporary buffer for speedup purposes*/
111
112 static void (* envelope_calc[5])(OscilRec *);
113 static void (* register_writes[256])(uint8_t, uint8_t, uint8_t);
114
115 int PMTab[8]; /*8 channels */
116 /*  this table is used for PM setup of LFO */
117
118 int AMTab[8]; /*8 channels */
119 /*  this table is used for AM setup of LFO */
120
121 static int decib45[16];
122 /*decibel table to convert from D1L values to index in lookup table*/
123
124 static int attack_curve[ENV_RES];
125
126 unsigned int divia[64]; //Attack dividers
127 unsigned int divid[64]; //Decay dividers
128 static unsigned int A_DELTAS[64+31]; //Attack deltas (64 keycodes + 31 RKS's = 95)
129 static unsigned int D_DELTAS[64+31]; //Decay  deltas (64 keycodes + 31 RKS's = 95)
130
131 float DT1Tab[32][4]={ /* 8 octaves * 4 key codes, 4 DT1 values */
132 /*
133  *  Table defines offset in Hertz from base frequency depending on KC and DT1
134  *  User's Manual page 21
135 */
136 /*OCT NOTE DT1=0 DT1=1  DT1=2  DT1=3*/
137 /* 0   0*/{0,    0,     0.053, 0.107},
138 /* 0   1*/{0,    0,     0.053, 0.107},
139 /* 0   2*/{0,    0,     0.053, 0.107},
140 /* 0   3*/{0,    0,     0.053, 0.107},
141 /* 1   0*/{0,    0.053, 0.107, 0.107},
142 /* 1   1*/{0,    0.053, 0.107, 0.160},
143 /* 1   2*/{0,    0.053, 0.107, 0.160},
144 /* 1   3*/{0,    0.053, 0.107, 0.160},
145 /* 2   0*/{0,    0.053, 0.107, 0.213},
146 /* 2   1*/{0,    0.053, 0.160, 0.213},
147 /* 2   2*/{0,    0.053, 0.160, 0.213},
148 /* 2   3*/{0,    0.053, 0.160, 0.267},
149 /* 3   0*/{0,    0.107, 0.213, 0.267},
150 /* 3   1*/{0,    0.107, 0.213, 0.320},
151 /* 3   2*/{0,    0.107, 0.213, 0.320},
152 /* 3   3*/{0,    0.107, 0.267, 0.373},
153 /* 4   0*/{0,    0.107, 0.267, 0.427},
154 /* 4   1*/{0,    0.160, 0.320, 0.427},
155 /* 4   2*/{0,    0.160, 0.320, 0.480},
156 /* 4   3*/{0,    0.160, 0.373, 0.533},
157 /* 5   0*/{0,    0.213, 0.427, 0.587},
158 /* 5   1*/{0,    0.213, 0.427, 0.640},
159 /* 5   2*/{0,    0.213, 0.480, 0.693},
160 /* 5   3*/{0,    0.267, 0.533, 0.747},
161 /* 6   0*/{0,    0.267, 0.587, 0.853},
162 /* 6   1*/{0,    0.320, 0.640, 0.907},
163 /* 6   2*/{0,    0.320, 0.693, 1.013},
164 /* 6   3*/{0,    0.373, 0.747, 1.067},
165 /* 7   0*/{0,    0.427, 0.853, 1.173},
166 /* 7   1*/{0,    0.427, 0.907, 1.173},
167 /* 7   2*/{0,    0.480, 1.013, 1.173},
168 /* 7   3*/{0,    0.533, 1.067, 1.173}
169 };
170
171 static uint16_t DT2Tab[4]={ /* 4 DT2 values */
172 /*
173  *   DT2 defines offset in cents from base note
174  *
175  *   The table below defines offset in deltas table...
176  *   User's Manual page 22
177  *   Values below were calculated using formula:  value = orig.val / 1.5625
178  *
179  * DT2=0 DT2=1 DT2=2 DT2=3
180  * 0     600   781   950
181  */
182         0,    384,  500,  608
183 };
184
185 static uint16_t KC_TO_INDEX[16*8];  /*16 note codes * 8 octaves */
186 /*translate key code KC (OCT2 OCT1 OCT0 N3 N2 N1 N0) into index in deltas table*/
187
188 static signed int DT1deltas[32][8];
189
190 static signed int deltas[9*12*64];/*9 octaves, 12 semitones, 64 'cents'  */
191 /*deltas in sintable (fixed point) to get the closest frequency possible */
192 /*there're 9 octaves because of DT2 (max 950 cents over base frequency)  */
193
194 static signed int LFOdeltas[256];  /*frequency deltas for LFO*/
195
196 void sin_init(void)
197 {
198         int x, i;
199         float m;
200
201         for(i=0; i<SIN_LEN; i++)
202         {
203                 m = sin(2 * PI * i / SIN_LEN);  /*count sin value*/
204
205                 if ((m < 0.0001) && (m > -0.0001)) /*is m very close to zero ?*/
206                         m = ENV_RES - 1;
207                 else
208                 {
209                         if (m > 0.0)
210                         {
211                                 m = 20 * log10(1.0 / m);      /* and how many decibels is it? */
212                                 m = m / ENV_STEP;
213                         }
214                         else
215                         {
216                                 m = 20 * log10(-1.0 / m);     /* and how many decibels is it? */
217                                 m = (m / ENV_STEP) + TL_TAB_LEN / 2;
218                         }
219                 }
220
221                 sin_tab[i] = &TL_TAB[(unsigned int)m];  /**/
222                 //if (errorlog) fprintf(errorlog,"sin %i = %i\n",i,sin_tab[i] );
223         }
224
225         for(x=0; x<TL_TAB_LEN/2; x++)
226         {
227                 if (x < ENV_RES)
228                 {
229                         if ((x * ENV_STEP) < 6.0)  /*have we passed 6 dB*/
230                         {       /*nope, we didn't */
231                                 m = ((1 << 12) - 1) / pow(10, x * ENV_STEP / 20);
232                         }
233                         else
234                         {
235                                 /*if yes, we simplify things (and the real chip */
236                                 /*probably does it also) and assume that - 6dB   */
237                                 /*halves the voltage (it _nearly_ does in fact)  */
238                                 m = TL_TAB[(int)((float)x - (6.0 / ENV_STEP))] / 2;
239                         }
240                 }
241                 else
242                 {
243                         m = 0;
244                 }
245
246                 TL_TAB[        x         ] = m;
247                 TL_TAB[x + TL_TAB_LEN / 2] = -m;
248                 //if (errorlog) fprintf(errorlog,"tl %04i =%08x\n",x,TL_TAB[x]);
249         }
250
251 /* create attack curve */
252         for(i=0; i<ENV_RES; i++)
253         {
254                 m = (ENV_RES - 1) / pow(10, i * (48.0 / ENV_RES) / 20);
255                 x = m * (1 << ENV_SH);
256                 attack_curve[ENV_RES - 1 - i] = x;
257                 //if (errorlog) fprintf(errorlog,"attack [%04x] = %08x Volt=%08x\n", ENV_RES-1-i, x/(1<<ENV_SH), TL_TAB[x/(1<<ENV_SH)] );
258         }
259
260         for(x=0; x<16; x++)
261         {
262                 i = (x < 15 ? x : x + 16) * (3.0 / ENV_STEP);  /*every 3 dB except for ALL '1' = 45dB+48dB*/
263                 i <<= ENV_SH;
264                 decib45[x] = i;
265                 //if (errorlog) fprintf(errorlog,"decib45[%04x]=%08x\n",x,i );
266         }
267 }
268
269 void hertz(void)
270 {
271         int i, j, oct;
272         long int mult;
273         float pom, pom2, m;
274         float scaler;   /* formula below is true for chip clock=3579545 */
275         /* so we need to scale its output accordingly to the chip clock */
276
277 /*this loop calculates Hertz values for notes from c#0 up to c-8*/
278 /*including 64 'cents' (100/64 which is 1.5625 of real cent) for each semitone*/
279
280         scaler = (float)YM2151_CLOCK / 3579545.0;
281
282         oct = 768;
283         mult = (long int)1 << FREQ_SH;
284
285         for(i=0; i<1*12*64; i++)
286         {
287                 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*/
288                 /*calculate phase increment for above precounted Hertz value*/
289                 pom2 = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
290
291                 deltas[i + oct * 4] = pom2 * 16;  /*oct 4 - center*/
292                 deltas[i + oct * 5] = deltas[oct * 4 + i] << 1; //oct 5
293                 deltas[i + oct * 6] = deltas[oct * 4 + i] << 2; //oct 6
294                 deltas[i + oct * 7] = deltas[oct * 4 + i] << 3; //oct 7
295                 deltas[i + oct * 8] = deltas[oct * 4 + i] << 4; //oct 8
296
297                 deltas[i + oct * 3] = deltas[oct * 4 + i] >> 1; //oct 3
298                 deltas[i + oct * 2] = deltas[oct * 4 + i] >> 2; //oct 2
299                 deltas[i + oct * 1] = deltas[oct * 4 + i] >> 3; //oct 1
300                 deltas[i + oct * 0] = deltas[oct * 4 + i] >> 4; //oct 0
301
302                 //if (errorlog) fprintf(errorlog,"deltas[%04i] = %08x\n",i,deltas[i]);
303         }
304
305         for(j=0; j<4; j++)
306         {
307                 for(i=0; i<32; i++)
308                 {
309                         pom = scaler * DT1Tab[i][j];
310                         //calculate phase increment for above precounted Hertz value
311                         DT1deltas[i][j] = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
312                         DT1deltas[i][j + 4] = -DT1deltas[i][j];
313                 }
314         }
315
316         mult = (long int)1 << LFO_SH;
317         m = (float)YM2151_CLOCK;
318
319         for(i=0; i<256; i++)
320         {
321                 j = i & 0x0F;
322                 pom = scaler * fabs((m / 65536 / (1 << (i / 16))) - (m / 65536 / 32 / (1 << (i / 16)) * (j + 1)));
323
324                 /*calculate phase increment for above precounted Hertz value*/
325                 pom2 = ((pom * SIN_LEN) / (float)YM2151_SAMPFREQ) * mult; /*fixed point*/
326                 LFOdeltas[0xFF - i] = pom2;
327                 //if (errorlog) fprintf(errorlog, "LFO[%02x] = %08x\n",0xff-i, LFOdeltas[0xff-i]);
328         }
329
330         /* calculate KC to index table */
331         j=0;
332         for(i=0; i<16*8; i++)
333         {
334                 KC_TO_INDEX[i] = (i >> 4) * 12 * 64 + j * 64 ;
335
336                 if ((i & 3) != 3)
337                         j++;    /* change note code */
338
339                 if ((i & 15) == 15)
340                         j = 0;  /* new octave */
341
342                 //if (errorlog) fprintf(errorlog,"NOTE[%i] = %i\n",i,KC_TO_INDEX[i]);
343         }
344
345         /* precalculate envelope times */
346         for(i=0; i<64; i++)
347         {
348                 pom = (16 << (i >> 2)) + (4 << (i >> 2)) * (i & 0x03);
349
350                 if ((i >> 2) == 0)
351                         pom = 1; //infinity
352
353                 if ((i >> 2) == 15)
354                         pom = 524288; //const
355
356                 divid[i] = pom;
357         }
358
359         for(i=0; i<64; i++)
360         {
361                 pom = ((128+64+32)<<(i>>2))+((32+16+8)<<(i>>2))*(i&0x03);
362
363                 if ((i>>2)==0)  pom=1;    //infinity
364
365                 if ((i>>2)==15)
366                 {
367                         if ((i & 0x03) == 3)
368                                 pom = 153293300; //zero attack time
369                         else
370                                 pom = 6422528; //const attack time
371                 }
372
373                 divia[i] = pom;
374         }
375
376         mult = (long int)1 << ENV_SH;
377
378         for(i=0; i<64; i++)
379         {
380                 if (divid[i] == 1)
381                         pom = 0;  //infinity
382                 else
383                         pom = (scaler * ENV_RES * mult) / ((float)YM2151_SAMPFREQ * ((float)YM2151_CLOCK / 1000.0 / (float)divid[i]));
384                 //if (errorlog) fprintf(errorlog,"i=%03i div=%i time=%f delta=%f\n",i,divid[i],
385                 //              (float)YM2151_CLOCK/1000.0/(float)divid[i], pom );
386                 D_DELTAS[i] = pom;
387         }
388
389         for (i=0; i<64; i++)
390         {
391                 if (divia[i] == 1)
392                         pom = 0;  //infinity
393                 else
394                         pom = (scaler * ENV_RES * mult) / ((float)YM2151_SAMPFREQ * ((float)YM2151_CLOCK / 1000.0 / (float)divia[i]));
395
396                 //if (errorlog) fprintf(errorlog,"i=%03i div=%i time=%f delta=%f\n",i,divia[i],
397                 //              (float)YM2151_CLOCK/1000.0/(float)divia[i], pom );
398                 A_DELTAS[i] = pom;
399         }
400
401         // This is only for speedup purposes -> to avoid testing if (keycode+RKS is
402         // over 63)
403         for(i=0; i<32; i++)
404         {
405                 D_DELTAS[64 + i] = D_DELTAS[63];
406                 A_DELTAS[64 + i] = A_DELTAS[63];
407         }
408
409         /* precalculate timers deltas */
410         /* User's Manual pages 15,16  */
411         mult = (int)1 << TIMER_SH;
412
413         for(i=0; i<1024; i++)
414         {
415                 /* ASG 980324: changed to compute both TimerA and TimerATime */
416                 pom = (64.0 * (1024.0 - i) / YM2151_CLOCK);
417                 TimerATime[i] = pom;
418                 TimerA[i] = pom * YM2151_SAMPFREQ * mult;  /*number of samples that timer period should last (fixed point) */
419         }
420
421         for(i=0; i<256; i++)
422         {
423                 /* ASG 980324: changed to compute both TimerB and TimerBTime */
424                 pom = (1024.0 * (256.0 - i) / YM2151_CLOCK);
425                 TimerBTime[i] = pom;
426                 TimerB[i] = pom * YM2151_SAMPFREQ * mult;  /*number of samples that timer period should last (fixed point) */
427         }
428 }
429
430 void envelope_attack(OscilRec * op)
431 {
432         if ((op->attack_volume -= op->delta_AR) < MIN_VOLUME_INDEX)  //is volume index min already ?
433         {
434                 op->volume = MIN_VOLUME_INDEX;
435                 op->state++;
436         }
437         else
438                 op->volume = attack_curve[op->attack_volume>>ENV_SH];
439 }
440
441 void envelope_decay(OscilRec * op)
442 {
443         if ((op->volume += op->delta_D1R) > op->D1L)
444         {
445                 //op->volume = op->D1L;
446                 op->state++;
447         }
448 }
449
450 void envelope_sustain(OscilRec * op)
451 {
452         if ((op->volume += op->delta_D2R) > MAX_VOLUME_INDEX)
453         {
454                 op->state = 4;
455                 op->volume = VOLUME_OFF;
456         }
457 }
458
459 void envelope_release(OscilRec * op)
460 {
461         if ((op->volume += op->delta_RR) > MAX_VOLUME_INDEX)
462         {
463                 op->state = 4;
464                 op->volume = VOLUME_OFF;
465         }
466 }
467
468 void envelope_nothing(OscilRec *op)
469 {
470 }
471
472 inline void envelope_KOFF(OscilRec * op)
473 {
474         op->state = 3; /*release*/
475 }
476
477 inline void envelope_KON(OscilRec * op)
478 {
479         /*this is to remove the gap time if TL>0*/
480         op->volume = VOLUME_OFF; //(ENV_RES - op->TL)<<ENV_SH; /***  <-  SURE ABOUT IT ?  No, but let's give it a try...*/
481         op->attack_volume = op->volume;
482         op->phase = 0;
483         op->state = 0;    /*KEY ON = attack*/
484         op->OscilFB = 0;  /*Clear feedback after key on */
485 }
486
487 void refresh_chip(YM2151 * PSG)
488 {
489         uint16_t kc_index_oscil, kc_index_channel, mul;
490         uint8_t op,v,kc;
491         signed char k,chan;
492         OscilRec * osc;
493
494         for(chan=7; chan>=0; chan--)
495         {
496                 kc = PSG->KC[chan];
497                 kc_index_channel = KC_TO_INDEX[kc] + PSG->KF[chan];
498                 kc >>=2;
499
500                 for(k=24; k>=0; k-=8)
501                 {
502                         op = chan + k;
503                         osc = &PSG->Oscils[op];
504
505 /*calc freq begin*/
506                         v = (PSG->Regs[YM_DT2_D2R_BASE + op] >> 6) & 0x03;   //DT2 value
507                         kc_index_oscil = kc_index_channel + DT2Tab[v]; //DT2 offset
508                         v = PSG->Regs[YM_DT1_MUL_BASE + op];
509                         mul = (v & 0x0F) << 1;
510
511                         if (mul)
512                                 osc->freq = deltas[kc_index_oscil] * mul;
513                         else
514                                 osc->freq = deltas[kc_index_oscil];
515
516                         osc->freq += DT1deltas[kc][(v >> 4) & 0x07];  //DT1 value
517 /*calc freq end*/
518
519 /*calc envelopes begin*/
520                         v = kc >> PSG->KS[op];
521                         osc->delta_AR  = A_DELTAS[ osc->AR + v];    /* 2*RR + RKS =max 95*/
522                         osc->delta_D1R = D_DELTAS[osc->D1R + v];    /* 2*RR + RKS =max 95*/
523                         osc->delta_D2R = D_DELTAS[osc->D2R + v];    /* 2*RR + RKS =max 95*/
524                         osc->delta_RR =  D_DELTAS[ osc->RR + v];    /* 2*RR + RKS =max 95*/
525 /*calc envelopes end*/
526                 }
527         }
528 }
529
530 void write_YM_NON_EMULATED(uint8_t n, uint8_t r, uint8_t v)
531 {
532         if (errorlog)
533                 fprintf(errorlog, "Write to non emulated register %02x value %02x\n", r, v);
534 }
535
536 void write_YM_KON(uint8_t n, uint8_t r, uint8_t v)
537 {
538         uint8_t chan;
539         YM2151 * PSG = &(YMPSG[n]);
540
541         chan = v & 0x07;
542
543         if (v & 0x08)
544                 envelope_KON(&PSG->Oscils[chan]);
545         else
546                 envelope_KOFF(&PSG->Oscils[chan]);
547
548         if (v & 0x10)
549                 envelope_KON(&PSG->Oscils[chan + 16]);
550         else
551                 envelope_KOFF(&PSG->Oscils[chan + 16]);
552
553         if (v & 0x20)
554                 envelope_KON(&PSG->Oscils[chan + 8]);
555         else
556                 envelope_KOFF(&PSG->Oscils[chan + 8]);
557
558         if (v & 0x40)
559                 envelope_KON(&PSG->Oscils[chan + 24]);
560         else
561                 envelope_KOFF(&PSG->Oscils[chan + 24]);
562 }
563
564 void write_YM_CLOCKA1(uint8_t n, uint8_t r, uint8_t v)
565 {
566         YMPSG[n].Regs[r] = v;
567 }
568
569 void write_YM_CLOCKA2(uint8_t n, uint8_t r, uint8_t v)
570 {
571         YMPSG[n].Regs[r] = v & 0x03;
572 }
573
574 void write_YM_CLOCKB(uint8_t n, uint8_t r, uint8_t v)
575 {
576         YMPSG[n].Regs[r] = v;
577 }
578
579 static void timer_callback_a(int n)
580 {
581         YM2151 * PSG = &YMPSG[n];
582 //      YM2151UpdateOne(n, cpu_scalebyfcount(YMBufSize));
583
584         if (PSG->handler)
585                 (*PSG->handler)();
586
587         PSG->TimA = 0;
588         PSG->TimIRQ |= 1;
589         PSG->TimATimer = 0;
590 }
591
592 static void timer_callback_b(int n)
593 {
594         YM2151 * PSG = &YMPSG[n];
595 //      YM2151UpdateOne(n, cpu_scalebyfcount(YMBufSize));
596
597         if (PSG->handler)
598                 (*PSG->handler)();
599
600         PSG->TimB = 0;
601         PSG->TimIRQ |= 2;
602         PSG->TimBTimer = 0;
603 }
604
605 void write_YM_CLOCKSET(uint8_t n, uint8_t r, uint8_t v)
606 {
607         YM2151 * PSG = &(YMPSG[n]);
608
609         v &= 0xBF;
610         //PSG->Regs[r]=v;
611 //      if (errorlog) fprintf(errorlog,"CSM= %01x FRESET=%02x, IRQEN=%02x, LOAD=%02x\n",v>>7,(v>>4)&0x03,(v>>2)&0x03,v&0x03 );
612
613         if (v & 0x80) //CSM
614         {}
615
616         /* ASG 980324: remove the timers if they exist */
617         if (PSG->TimATimer)
618                 timer_remove(PSG->TimATimer);
619
620         if (PSG->TimBTimer)
621                 timer_remove(PSG->TimBTimer);
622
623         PSG->TimATimer = 0;
624         PSG->TimBTimer = 0;
625
626         if (v & 0x01) //LOAD A
627         {
628                 PSG->TimA = 1;
629                 PSG->TimAVal = TimerA[(PSG->Regs[YM_CLOCKA1] << 2) | PSG->Regs[YM_CLOCKA2]];
630                 /* ASG 980324: added a real timer if we have a handler */
631
632                 if (PSG->handler)
633                         PSG->TimATimer = timer_set(TimerATime[(PSG->Regs[YM_CLOCKA1] << 2) | PSG->Regs[YM_CLOCKA2]], n, timer_callback_a);
634         }
635         else
636                 PSG->TimA = 0;
637
638         if (v & 0x02) //load B
639         {
640                 PSG->TimB = 1;
641                 PSG->TimBVal = TimerB[PSG->Regs[YM_CLOCKB]];
642
643                 /* ASG 980324: added a real timer if we have a handler */
644                 if (PSG->handler)
645                         PSG->TimBTimer = timer_set (TimerBTime[PSG->Regs[YM_CLOCKB]], n, timer_callback_b);
646         }
647         else
648                 PSG->TimB = 0;
649
650         if (v & 0x04) //IRQEN A
651         {}
652
653         if (v & 0x08) //IRQEN B
654         {}
655
656         if (v & 0x10) //FRESET A
657         {
658                 PSG->TimIRQ &= 0xFE;
659         }
660
661         if (v & 0x20) //FRESET B
662         {
663                 PSG->TimIRQ &= 0xFD;
664         }
665 }
666
667 void write_YM_CT1_CT2_W(uint8_t n, uint8_t r, uint8_t v)
668 {
669         YMPSG[n].Regs[r] = v;
670 }
671
672 void write_YM_CONNECT_BASE(uint8_t n, uint8_t r, uint8_t v)
673 {
674         // NOTE: L/R Channel enables are ignored! This emu is mono!
675         YM2151 * PSG = &(YMPSG[n]);
676
677         //PSG->Regs[r] = v;
678         uint8_t chan = r - YM_CONNECT_BASE;
679
680         PSG->ConnectTab[chan] = v & 7; /*connection number*/
681         PSG->FeedBack[chan] = FEED[(v >> 3) & 7];
682 }
683
684 void write_YM_KC_BASE(uint8_t n, uint8_t r, uint8_t v)
685 {
686         YMPSG[n].KC[r - YM_KC_BASE] = v;
687         //freq_calc(chan,PSG);
688 }
689
690 void write_YM_KF_BASE(uint8_t n, uint8_t r, uint8_t v)
691 {
692         YMPSG[n].KF[r - YM_KF_BASE] = v >> 2;
693         //freq_calc(chan,PSG);
694 }
695
696 void write_YM_PMS_AMS_BASE(uint8_t n, uint8_t r, uint8_t v)
697 {
698 //      uint8_t chan, i;
699         YM2151 * PSG = &(YMPSG[n]);
700         PSG->Regs[r] = v;
701         uint8_t chan = r - YM_PMS_AMS_BASE;
702
703         PMTab[chan] = v >> 4;  //PMS;
704
705 //      if (i && errorlog)
706 //              fprintf(errorlog,"PMS CHN %02x =%02x\n", chan, i);
707
708         AMTab[chan] = v & 0x03; //AMS;
709
710 //      if (i && errorlog)
711 //              fprintf(errorlog,"AMS CHN %02x =%02x\n", chan, i);
712
713 }
714
715 void write_YM_DT1_MUL_BASE(uint8_t n, uint8_t r, uint8_t v)
716 {
717         YMPSG[n].Regs[r] = v;
718         //freq_calc(chan,PSG);
719 }
720
721 void write_YM_TL_BASE(uint8_t n, uint8_t r, uint8_t v)
722 {
723         v &= 0x7F;
724         YMPSG[n].Oscils[r - YM_TL_BASE].TL =  v << (ENV_BITS - 7); /*7bit TL*/
725 }
726
727 void write_YM_KS_AR_BASE(uint8_t n, uint8_t r, uint8_t v)
728 {
729         uint8_t op;
730         YM2151 * PSG;
731
732         op = r - YM_KS_AR_BASE;
733         PSG = &(YMPSG[n]);
734
735         PSG->KS[op] = 3 - (v >> 6);
736         PSG->Oscils[op].AR = (v & 0x1F) << 1;
737 }
738
739 void write_YM_AMS_D1R_BASE(uint8_t n, uint8_t r, uint8_t v)
740 {
741         uint8_t op = r - YM_AMS_D1R_BASE;
742
743         if ((v & 0x80) && errorlog)
744                 fprintf(errorlog,"AMS ON oper%02x\n", op);
745
746         //HERE something to do with AMS;
747
748         YMPSG[n].Oscils[op].D1R = (v & 0x1F) << 1;
749 }
750
751 void write_YM_DT2_D2R_BASE(uint8_t n, uint8_t r, uint8_t v)
752 {
753         YM2151 * PSG = &(YMPSG[n]);
754         OscilRec * osc = &PSG->Oscils[r - YM_DT2_D2R_BASE];
755         PSG->Regs[r] = v;
756
757         osc->D2R = (v & 0x1F) << 1;
758         //freq_calc(chan,PSG);
759 }
760
761 void write_YM_D1L_RR_BASE(uint8_t n, uint8_t r, uint8_t v)
762 {
763     OscilRec * osc = &YMPSG[n].Oscils[r - YM_D1L_RR_BASE];
764
765         osc->D1L = decib45[(v >> 4) & 0x0F];
766         osc->RR = ((v & 0x0F) << 2) | 0x02;
767 }
768
769 /*
770 ** Initialize YM2151 emulator(s).
771 **
772 ** 'num' is the number of virtual YM2151's to allocate
773 ** 'clock' is the chip clock
774 ** 'rate' is sampling rate and 'bufsiz' is the size of the
775 ** buffer that should be updated at each interval
776 */
777 //int YMInit(int num, int clock, int rate, int sample_bits, int bufsiz)//, SAMPLE ** buffer)
778 int YMInit(int clock, int rate)
779 {
780         int i;
781
782         if (YMPSG)
783                 return (-1);    /* duplicate init. */
784
785 //      YMNumChips = num;
786         YMNumChips = 1;
787         YM2151_SAMPFREQ = rate;
788
789 #if 0
790         if (sample_bits == 16)
791                 sample_16bit = 1;
792         else
793                 sample_16bit = 0;
794 #endif
795
796         YM2151_CLOCK = clock;
797 //      YMBufSize = bufsiz;
798
799         envelope_calc[0] = envelope_attack;
800         envelope_calc[1] = envelope_decay;
801         envelope_calc[2] = envelope_sustain;
802         envelope_calc[3] = envelope_release;
803         envelope_calc[4] = envelope_nothing;
804
805         for(i=0; i<256; i++)
806                 register_writes[i] = write_YM_NON_EMULATED;
807
808         register_writes[YM_KON] = write_YM_KON;
809         register_writes[YM_CLOCKA1] = write_YM_CLOCKA1;
810         register_writes[YM_CLOCKA2] = write_YM_CLOCKA2;
811         register_writes[YM_CLOCKB] = write_YM_CLOCKB;
812         register_writes[YM_CLOCKSET] = write_YM_CLOCKSET;
813         register_writes[YM_CT1_CT2_W] = write_YM_CT1_CT2_W;
814
815         for(i=YM_CONNECT_BASE; i<YM_CONNECT_BASE+8; i++)
816                 register_writes[i] = write_YM_CONNECT_BASE;
817
818         for(i=YM_KC_BASE; i<YM_KC_BASE+8; i++)
819                 register_writes[i] = write_YM_KC_BASE;
820
821         for(i=YM_KF_BASE; i<YM_KF_BASE+8; i++)
822                 register_writes[i] = write_YM_KF_BASE;
823
824         for(i=YM_PMS_AMS_BASE; i<YM_PMS_AMS_BASE+8; i++)
825                 register_writes[i] = write_YM_PMS_AMS_BASE;
826
827         for(i=YM_DT1_MUL_BASE; i<YM_DT1_MUL_BASE+32; i++)
828                 register_writes[i] = write_YM_DT1_MUL_BASE;
829
830         for(i=YM_TL_BASE; i<YM_TL_BASE+32; i++)
831                 register_writes[i] = write_YM_TL_BASE;
832
833         for(i=YM_KS_AR_BASE; i<YM_KS_AR_BASE+32; i++)
834                 register_writes[i] = write_YM_KS_AR_BASE;
835
836         for(i=YM_AMS_D1R_BASE; i<YM_AMS_D1R_BASE+32; i++)
837                 register_writes[i] = write_YM_AMS_D1R_BASE;
838
839         for(i=YM_DT2_D2R_BASE; i<YM_DT2_D2R_BASE+32; i++)
840                 register_writes[i] = write_YM_DT2_D2R_BASE;
841
842         for(i=YM_D1L_RR_BASE; i<YM_D1L_RR_BASE+32; i++)
843                 register_writes[i] = write_YM_D1L_RR_BASE;
844
845         YMPSG = (YM2151 *)malloc(sizeof(YM2151) * YMNumChips);
846
847         if (YMPSG == NULL)
848                 return (1);
849
850         TL_TAB = (signed int *)malloc(sizeof(signed int) * TL_TAB_LEN);
851
852         if (TL_TAB == NULL)
853                 return (1);
854
855 //      BuffTemp = (signed int *)malloc(sizeof(signed int) * YMBufSize);
856         // 16K ought to be enough for anybody
857         BuffTemp = (signed int *)malloc(sizeof(signed int) * 16384);
858
859         if (BuffTemp == NULL)
860                 return (1);
861
862         hertz();
863         sin_init();
864
865         for(i=0; i<YMNumChips; i++)
866         {
867                 YMPSG[i].Buf = 0;//buffer[i];
868                 YMPSG[i].bufp = 0;
869                 YMResetChip(i);
870         }
871
872         return 0;
873 }
874
875 void YMShutdown()
876 {
877         if (!YMPSG)
878                 return;
879
880         free(YMPSG);
881         YMPSG = NULL;
882
883         if (TL_TAB)
884         {
885                 free(TL_TAB);
886                 TL_TAB = NULL;
887         }
888
889         if (BuffTemp)
890         {
891                 free(BuffTemp);
892                 BuffTemp = NULL;
893         }
894
895         YM2151_SAMPFREQ = YMBufSize = 0;
896 }
897
898 /* write a register on YM2151 chip number 'n' */
899 void YMWriteReg(int n, int r, int v)
900 {
901         register_writes[(uint8_t)r]((uint8_t)n, (uint8_t)r, (uint8_t)v);
902 }
903
904 uint8_t YMReadReg(uint8_t n)
905 {
906         return YMPSG[n].TimIRQ;
907 }
908
909 /*
910 ** reset all chip registers.
911 */
912 void YMResetChip(int num)
913 {
914         int i;
915         YM2151 * PSG = &(YMPSG[num]);
916
917 //      memset(PSG->Buf, '\0', YMBufSize);
918
919         /* ASG 980324 -- reset the timers before writing to the registers */
920         PSG->TimATimer = 0;
921         PSG->TimBTimer = 0;
922
923         /* initialize hardware registers */
924         for(i=0; i<256; i++)
925                 PSG->Regs[i] = 0;
926
927         for(i=0; i<32; i++)
928         {
929                 memset(&PSG->Oscils[i], '\0', sizeof(OscilRec));
930                 PSG->Oscils[i].volume = VOLUME_OFF;
931                 PSG->Oscils[i].state = 4;  //envelope off
932         }
933
934         for(i=0; i<8; i++)
935         {
936                 PSG->ConnectTab[i] = 0;
937                 PSG->FeedBack[i] = 0;
938         }
939
940         PSG->TimA = 0;
941         PSG->TimB = 0;
942         PSG->TimAVal = 0;
943         PSG->TimBVal = 0;
944         PSG->TimIRQ = 0;
945 }
946
947 static inline signed int op_calc(OscilRec * OP, signed int pm)
948 {
949         return sin_tab[(((OP->phase += OP->freq) >> FREQ_SH) + (pm)) & SIN_MASK]
950                 [OP->TL + (OP->volume >> ENV_SH)];
951 }
952
953 //void YM2151UpdateOne(int num, int endp)
954 void YM2151UpdateOne(void * BUF, int endp)
955 {
956 //    YM2151 * PSG = &(YMPSG[num]);
957         YM2151 * PSG = &(YMPSG[0]);
958         PSG->bufp = 0;
959 //    SAMPLE * BUF;
960         signed int * PSGBUF;
961         OscilRec * OP0, * OP1, * OP2, * OP3;
962         uint16_t i;
963         signed int k, wy;
964
965         refresh_chip(PSG);
966
967         //calculate timers...
968         if (PSG->TimA)
969         {
970                 PSG->TimAVal -= ((endp - PSG->bufp) << TIMER_SH);
971
972                 if (PSG->TimAVal <= 0)
973                 {
974                         PSG->TimA = 0;
975                         PSG->TimIRQ |= 1;
976                         /* ASG 980324 - handled by real timers now
977                         if (PSG->handler !=0) PSG->handler();*/
978                 }
979         }
980
981         if (PSG->TimB)
982         {
983                 PSG->TimBVal -= ((endp - PSG->bufp) << TIMER_SH);
984
985                 if (PSG->TimBVal <= 0)
986                 {
987                         PSG->TimB = 0;
988                         PSG->TimIRQ |= 2;
989                         /* ASG 980324 - handled by real timers now
990                         if (PSG->handler !=0) PSG->handler();*/
991                 }
992         }
993
994         OP0 = &PSG->Oscils[0     ];
995         OP1 = &PSG->Oscils[0 +  8];
996         OP2 = &PSG->Oscils[0 + 16];
997         OP3 = &PSG->Oscils[0 + 24];
998
999         for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1000         {
1001                 //chan0
1002                 envelope_calc[OP0->state](OP0);
1003                 envelope_calc[OP1->state](OP1);
1004                 envelope_calc[OP2->state](OP2);
1005                 envelope_calc[OP3->state](OP3);
1006
1007                 wy = op_calc(OP0, OP0->OscilFB);
1008
1009                 if (PSG->FeedBack[0])
1010                         OP0->OscilFB = wy >> PSG->FeedBack[0];
1011                 else
1012                         OP0->OscilFB = 0;
1013
1014                 switch(PSG->ConnectTab[0])
1015                 {
1016                 case 0: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, wy))); break;
1017                 case 1: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, 0) + wy)); break;
1018                 case 2: *(PSGBUF) = op_calc(OP3, op_calc(OP1, op_calc(OP2, 0)) + wy); break;
1019                 case 3: *(PSGBUF) = op_calc(OP3, op_calc(OP2, wy) + op_calc(OP1, 0)); break;
1020                 case 4: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP3, op_calc(OP1, 0)); break;
1021                 case 5: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP1, wy) + op_calc(OP3, wy); break;
1022                 case 6: *(PSGBUF) = op_calc(OP2, wy) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
1023                 default: *(PSGBUF) = wy + op_calc(OP2, 0) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
1024                 }
1025         }
1026
1027         //chan1
1028         OP0 = &PSG->Oscils[1     ];
1029         OP1 = &PSG->Oscils[1 +  8];
1030         OP2 = &PSG->Oscils[1 + 16];
1031         OP3 = &PSG->Oscils[1 + 24];
1032
1033         for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1034         {
1035                 envelope_calc[OP0->state](OP0);
1036                 envelope_calc[OP1->state](OP1);
1037                 envelope_calc[OP2->state](OP2);
1038                 envelope_calc[OP3->state](OP3);
1039
1040                 wy = op_calc(OP0, OP0->OscilFB);
1041
1042                 if (PSG->FeedBack[1])
1043                                 OP0->OscilFB = wy >> PSG->FeedBack[1];
1044                 else
1045                                 OP0->OscilFB = 0;
1046
1047                 switch(PSG->ConnectTab[1])
1048                 {
1049                 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1050                 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1051                 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1052                 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1053                 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1054                 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1055                 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1056                 default: *(PSGBUF) += wy + op_calc(OP2, 0) + op_calc(OP1, 0) + op_calc(OP3, 0); break;
1057                 }
1058         }
1059
1060 //chan2
1061         OP0 = &PSG->Oscils[2     ];
1062         OP1 = &PSG->Oscils[2 +  8];
1063         OP2 = &PSG->Oscils[2 + 16];
1064         OP3 = &PSG->Oscils[2 + 24];
1065
1066 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1067 {
1068         envelope_calc[OP0->state](OP0);
1069         envelope_calc[OP1->state](OP1);
1070         envelope_calc[OP2->state](OP2);
1071         envelope_calc[OP3->state](OP3);
1072
1073         wy = op_calc(OP0, OP0->OscilFB);
1074         if (PSG->FeedBack[2])
1075                         OP0->OscilFB = wy >> PSG->FeedBack[2];
1076         else
1077                         OP0->OscilFB = 0;
1078
1079         switch(PSG->ConnectTab[2])
1080         {
1081         case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1082         case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1083         case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1084         case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1085         case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1086         case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1087         case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1088         default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1089         }
1090 }
1091
1092 //chan3
1093         OP0 = &PSG->Oscils[3     ];
1094         OP1 = &PSG->Oscils[3 +  8];
1095         OP2 = &PSG->Oscils[3 + 16];
1096         OP3 = &PSG->Oscils[3 + 24];
1097
1098 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1099 {
1100         envelope_calc[OP0->state](OP0);
1101         envelope_calc[OP1->state](OP1);
1102         envelope_calc[OP2->state](OP2);
1103         envelope_calc[OP3->state](OP3);
1104
1105         wy = op_calc(OP0, OP0->OscilFB);
1106         if (PSG->FeedBack[3])
1107                         OP0->OscilFB = wy >> PSG->FeedBack[3];
1108         else
1109                         OP0->OscilFB = 0;
1110
1111         switch(PSG->ConnectTab[3])
1112         {
1113         case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1114         case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1115         case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1116         case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1117         case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1118         case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1119         case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1120         default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1121         }
1122 }
1123
1124         //chan4
1125         OP0 = &PSG->Oscils[4     ];
1126         OP1 = &PSG->Oscils[4 +  8];
1127         OP2 = &PSG->Oscils[4 + 16];
1128         OP3 = &PSG->Oscils[4 + 24];
1129
1130         for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1131         {
1132                 envelope_calc[OP0->state](OP0);
1133                 envelope_calc[OP1->state](OP1);
1134                 envelope_calc[OP2->state](OP2);
1135                 envelope_calc[OP3->state](OP3);
1136
1137                 wy = op_calc(OP0, OP0->OscilFB);
1138
1139                 if (PSG->FeedBack[4])
1140                         OP0->OscilFB = wy >> PSG->FeedBack[4];
1141                 else
1142                         OP0->OscilFB = 0;
1143
1144                 switch(PSG->ConnectTab[4])
1145                 {
1146                 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1147                 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1148                 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1149                 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1150                 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1151                 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1152                 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1153                 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1154                 }
1155         }
1156
1157         //chan5
1158         OP0 = &PSG->Oscils[5     ];
1159         OP1 = &PSG->Oscils[5 +  8];
1160         OP2 = &PSG->Oscils[5 + 16];
1161         OP3 = &PSG->Oscils[5 + 24];
1162
1163 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1164 {
1165         envelope_calc[OP0->state](OP0);
1166         envelope_calc[OP1->state](OP1);
1167         envelope_calc[OP2->state](OP2);
1168         envelope_calc[OP3->state](OP3);
1169
1170         wy = op_calc(OP0, OP0->OscilFB);
1171         if (PSG->FeedBack[5])
1172                         OP0->OscilFB = wy >> PSG->FeedBack[5];
1173         else
1174                         OP0->OscilFB = 0;
1175
1176         switch(PSG->ConnectTab[5])
1177         {
1178         case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1179         case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1180         case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1181         case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1182         case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1183         case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1184         case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1185         default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1186         }
1187 }
1188
1189 //chan6
1190         OP0 = &PSG->Oscils[6     ];
1191         OP1 = &PSG->Oscils[6 +  8];
1192         OP2 = &PSG->Oscils[6 + 16];
1193         OP3 = &PSG->Oscils[6 + 24];
1194
1195 for( PSGBUF = &BuffTemp[PSG->bufp]; PSGBUF < &BuffTemp[endp]; PSGBUF++ )
1196 {
1197         envelope_calc[OP0->state](OP0);
1198         envelope_calc[OP1->state](OP1);
1199         envelope_calc[OP2->state](OP2);
1200         envelope_calc[OP3->state](OP3);
1201
1202         wy = op_calc(OP0, OP0->OscilFB);
1203         if (PSG->FeedBack[6])
1204                         OP0->OscilFB = wy >> PSG->FeedBack[6];
1205         else
1206                         OP0->OscilFB = 0;
1207
1208         switch(PSG->ConnectTab[6])
1209         {
1210         case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1211         case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1212         case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1213         case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1214         case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1215         case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1216         case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1217         default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1218         }
1219 }
1220
1221         //chan7
1222         OP0 = &PSG->Oscils[7     ];
1223         OP1 = &PSG->Oscils[7 +  8];
1224         OP2 = &PSG->Oscils[7 + 16];
1225         OP3 = &PSG->Oscils[7 + 24];
1226
1227         for(PSGBUF=&BuffTemp[PSG->bufp]; PSGBUF<&BuffTemp[endp]; PSGBUF++)
1228         {
1229                 envelope_calc[OP0->state](OP0);
1230                 envelope_calc[OP1->state](OP1);
1231                 envelope_calc[OP2->state](OP2);
1232                 envelope_calc[OP3->state](OP3);
1233
1234                 wy = op_calc(OP0, OP0->OscilFB);
1235
1236                 if (PSG->FeedBack[7])
1237                         OP0->OscilFB = wy >> PSG->FeedBack[7];
1238                 else
1239                         OP0->OscilFB = 0;
1240
1241                 switch(PSG->ConnectTab[7])
1242                 {
1243                 case 0: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,wy) ) );   break;
1244                 case 1: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)+wy ) ); break;
1245                 case 2: *(PSGBUF) += op_calc(OP3, op_calc(OP1, op_calc(OP2,0)) +wy ); break;
1246                 case 3: *(PSGBUF) += op_calc(OP3, op_calc(OP2, wy)+op_calc(OP1,0) );  break;
1247                 case 4: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP3, op_calc(OP1,0));  break;
1248                 case 5: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1, wy) + op_calc(OP3,wy); break;
1249                 case 6: *(PSGBUF) += op_calc(OP2,wy) + op_calc(OP1,0) + op_calc(OP3,0);    break;
1250                 default:*(PSGBUF) += wy + op_calc(OP2,0) + op_calc(OP1,0) + op_calc(OP3,0);break;
1251                 }
1252         }
1253
1254 //      BUF = PSG->Buf;
1255         PSGBUF = &BuffTemp[PSG->bufp];
1256
1257         for(i=PSG->bufp; i<endp; i++)
1258         {
1259                 k = *(PSGBUF++);
1260
1261 #if 1
1262 //              if (sample_16bit)
1263                 {
1264                         /*16 bit mode*/
1265                         k >>= FINAL_SH16;  //AUDIO_CONV
1266 // We don't shift by 2, as it's too loud (eventually, we need to do proper volume control here)
1267 //                      k <<= 2;
1268                         k <<= 1;
1269
1270                         if (k > 32767)
1271                                 k = 32767;
1272                         else if (k < -32768)
1273                                 k = -32768;
1274
1275                         ((uint16_t *)BUF)[i] = (uint16_t)k;
1276                 }
1277 #else
1278 //              else
1279                 {
1280                         /*8 bit mode*/
1281                         k >>= FINAL_SH8;  //AUDIO_CONV
1282
1283                         if (k > 127)
1284                                 k = 127;
1285                         else if (k < -128)
1286                                 k = -128;
1287
1288                         ((uint8_t *)BUF)[i] = (uint8_t)k;
1289                 }
1290 #endif
1291         }
1292
1293         PSG->bufp = endp;
1294 }
1295
1296 /*
1297 ** called to update all chips
1298 */
1299 void YM2151Update(void)
1300 {
1301         int i;
1302         for(i=0; i<YMNumChips; i++)
1303         {
1304                 if (YMPSG[i].bufp < YMBufSize)
1305 ;//                     YM2151UpdateOne(i, YMBufSize);
1306
1307                 YMPSG[i].bufp = 0;
1308         }
1309 }
1310
1311 /*
1312 ** return the buffer into which YM2151Update() has just written it's sample
1313 ** data
1314 */
1315 SAMPLE * YMBuffer(int n)
1316 {
1317         return YMPSG[n].Buf;
1318 }
1319
1320 void YMSetIrqHandler(int n, void(* handler)(void))
1321 {
1322         YMPSG[n].handler = handler;
1323 }