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