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