OSDN Git Service

Merge branch 'master' of github.com:Artanejp/common_source_project-fm7 into 019938ffe...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmgen / opna.cpp
1 // ---------------------------------------------------------------------------
2 //      OPN/A/B interface with ADPCM support
3 //      Copyright (C) cisc 1998, 2001.
4 // ---------------------------------------------------------------------------
5 //      $Id: opna.cpp,v 1.70 2004/02/06 13:13:39 cisc Exp $
6
7 #include "headers.h"
8 #include "misc.h"
9 #include "opna.h"
10 #include "fmgeninl.h"
11
12 #include "../../fileio.h"
13
14 #define BUILD_OPN
15 #define BUILD_OPNA
16 #define BUILD_OPNB
17 #if defined(_USE_AGAR)
18 # ifndef MAX_PATH
19 #  define MAX_PATH AG_PATHNAME_MAX
20 # endif
21 #endif
22
23 #ifdef USE_QT
24 # ifndef MAX_PATH
25 #   define MAX_PATH 2048
26 # endif
27 #endif
28
29
30 //      TOFIX:
31 //       OPN ch3 \82ª\8fí\82ÉPrepare\82Ì\91Î\8fÛ\82Æ\82È\82Á\82Ä\82µ\82Ü\82¤\8fá\8aQ
32
33
34 // ---------------------------------------------------------------------------
35 //      OPNA: ADPCM \83f\81[\83^\82Ì\8ai\94[\95û\8e®\82Ì\88á\82¢ (8bit/1bit) \82ð\83G\83~\83\85\83\8c\81[\83g\82µ\82È\82¢
36 //      \82±\82Ì\83I\83v\83V\83\87\83\93\82ð\97L\8cø\82É\82·\82é\82Æ ADPCM \83\81\83\82\83\8a\82Ö\82Ì\83A\83N\83Z\83X(\93Á\82É 8bit \83\82\81[\83h)\82ª
37 //      \91½\8f­\8cy\82­\82È\82é\82©\82à
38 //
39 //#define NO_BITTYPE_EMULATION
40
41 #ifdef BUILD_OPNA
42 #include "../../fileio.h"
43 #endif
44
45 namespace FM
46 {
47
48 // ---------------------------------------------------------------------------
49 //      OPNBase
50
51 #if defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB)
52
53 uint32  OPNBase::lfotable[8];                   // OPNA/B \97p
54
55 OPNBase::OPNBase()
56 {
57         prescale = 0;
58 }
59
60 //      \83p\83\89\83\81\81[\83^\83Z\83b\83g
61 void OPNBase::SetParameter(Channel4* ch, uint addr, uint data)
62 {
63         const static uint slottable[4] = { 0, 2, 1, 3 };
64         const static uint8 sltable[16] = 
65         {
66                   0,   4,   8,  12,  16,  20,  24,  28,
67                  32,  36,  40,  44,  48,  52,  56, 124,
68         };
69         
70         if ((addr & 3) < 3)
71         {
72                 uint slot = slottable[(addr >> 2) & 3];
73                 Operator* op = &ch->op[slot];
74
75                 switch ((addr >> 4) & 15)
76                 {
77                 case 3: // 30-3E DT/MULTI
78                         op->SetDT((data >> 4) & 0x07);
79                         op->SetMULTI(data & 0x0f);
80                         break;
81                         
82                 case 4: // 40-4E TL
83                         op->SetTL(data & 0x7f, ((regtc & 0xc0) == 0x80) && (csmch == ch));
84                         break;
85                         
86                 case 5: // 50-5E KS/AR
87                         op->SetKS((data >> 6) & 3);
88                         op->SetAR((data & 0x1f) * 2);
89                         break;
90                         
91                 case 6: // 60-6E DR/AMON
92                         op->SetDR((data & 0x1f) * 2);
93                         op->SetAMON((data & 0x80) != 0);
94                         break;
95                         
96                 case 7: // 70-7E SR
97                         op->SetSR((data & 0x1f) * 2);
98                         break;
99                         
100                 case 8: // 80-8E SL/RR
101                         op->SetSL(sltable[(data >> 4) & 15]);
102                         op->SetRR((data & 0x0f) * 4 + 2);
103                         break;
104                         
105                 case 9: // 90-9E SSG-EC
106                         op->SetSSGEC(data & 0x0f);
107                         break;
108                 }
109         }
110 }
111
112 //      \83\8a\83Z\83b\83g
113 void OPNBase::Reset()
114 {
115         status = 0;
116         interrupt = false;
117         SetPrescaler(0);
118         Timer::Reset();
119         psg.Reset();
120 }
121
122 //      \8a\84\82è\8d\9e\82Ý\90M\8d\86\82Ì\8eæ\93¾
123 bool OPNBase::ReadIRQ()
124 {
125         return interrupt;
126 }
127
128 //      \83v\83\8a\83X\83P\81[\83\89\90Ý\92è
129 void OPNBase::SetPrescaler(uint p)
130 {
131         static const char table[3][2] = { { 6, 4 }, { 3, 2 }, { 2, 1 } };
132         static const uint8 table2[8] = { 108,  77,  71,  67,  62,  44,  8,  5 };
133         // 512
134         if (prescale != p)
135         {
136                 prescale = p;
137                 assert(0 <= prescale && prescale < 3);
138                 
139                 uint fmclock = clock / table[p][0] / 12;
140                 
141                 rate = psgrate;
142                 
143                 // \8d\87\90¬\8eü\94g\90\94\82Æ\8fo\97Í\8eü\94g\90\94\82Ì\94ä
144                 assert(fmclock < (0x80000000 >> FM_RATIOBITS));
145                 uint ratio = ((fmclock << FM_RATIOBITS) + rate/2) / rate;
146
147                 SetTimerPrescaler(table[p][0] * 12);
148 //              MakeTimeTable(ratio);
149                 chip.SetRatio(ratio);
150                 psg.SetClock(clock / table[p][1], psgrate);
151
152                 for (int i=0; i<8; i++)
153                 {
154                         lfotable[i] = (ratio << (2+FM_LFOCBITS-FM_RATIOBITS)) / table2[i];
155                 }
156         }
157 }
158
159 //      \8f\89\8aú\89»
160 bool OPNBase::Init(uint c, uint r)
161 {
162         clock = c;
163         psgrate = r;
164
165         return true;
166 }
167
168 //      \89¹\97Ê\90Ý\92è
169 void OPNBase::SetVolumeFM(int db)
170 {
171         db = Min(db, 20);
172         if (db > -192)
173                 fmvolume = int(16384.0 * pow(10.0, db / 40.0));
174         else
175                 fmvolume = 0;
176 }
177
178 //      \83^\83C\83}\81[\8e\9e\8aÔ\8f\88\97\9d
179 void OPNBase::TimerA()
180 {
181         if ((regtc & 0xc0) == 0x80)
182         {
183                 csmch->KeyControl(0x00);
184                 csmch->KeyControl(0x0f);
185         }
186 }
187
188 //      \8a\84\82è\8d\9e\82Ý\90M\8d\86\82Ì\90Ý\92è
189 void OPNBase::Intr(bool value)
190 {
191         interrupt = value;
192 }
193
194 // ---------------------------------------------------------------------------
195 //      \83X\83e\81[\83g\83Z\81[\83u
196 //
197 #define OPN_BASE_STATE_VERSION  1
198
199 void OPNBase::SaveState(void *f)
200 {
201         FILEIO *state_fio = (FILEIO *)f;
202         
203         state_fio->FputUint32(OPN_BASE_STATE_VERSION);
204         
205         Timer::SaveState(f);
206         state_fio->FputInt32(fmvolume);
207         state_fio->FputUint32(clock);
208         state_fio->FputUint32(rate);
209         state_fio->FputUint32(psgrate);
210         state_fio->FputUint32(status);
211         state_fio->FputBool(interrupt);
212         state_fio->FputUint8(prescale);
213         chip.SaveState(f);
214         psg.SaveState(f);
215 }
216
217 bool OPNBase::LoadState(void *f)
218 {
219         FILEIO *state_fio = (FILEIO *)f;
220         
221         if(state_fio->FgetUint32() != OPN_BASE_STATE_VERSION) {
222                 return false;
223         }
224         if(!Timer::LoadState(f)) {
225                 return false;
226         }
227         fmvolume = state_fio->FgetInt32();
228         clock = state_fio->FgetUint32();
229         rate = state_fio->FgetUint32();
230         psgrate = state_fio->FgetUint32();
231         status = state_fio->FgetUint32();
232         interrupt = state_fio->FgetBool();
233         prescale = state_fio->FgetUint8();
234         if(!chip.LoadState(f)) {
235                 return false;
236         }
237         if(!psg.LoadState(f)) {
238                 return false;
239         }
240         return true;
241 }
242
243 #endif // defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB)
244
245 // ---------------------------------------------------------------------------
246 //      YM2203
247 //
248 #ifdef BUILD_OPN
249
250 OPN::OPN()
251 {
252         SetVolumeFM(0);
253         SetVolumePSG(0);
254
255         csmch = &ch[2];
256
257         for (int i=0; i<3; i++)
258         {
259                 ch[i].SetChip(&chip);
260                 ch[i].SetType(typeN);
261         }
262 }
263
264 //      \8f\89\8aú\89»
265 bool OPN::Init(uint c, uint r, bool ip, const char*)
266 {
267         if (!SetRate(c, r, ip))
268                 return false;
269         
270         Reset();
271
272         SetVolumeFM(0);
273         SetVolumePSG(0);
274         SetChannelMask(0);
275         return true;
276 }
277
278 //      \83T\83\93\83v\83\8a\83\93\83O\83\8c\81[\83g\95Ï\8dX
279 bool OPN::SetRate(uint c, uint r, bool)
280 {
281         OPNBase::Init(c, r);
282         RebuildTimeTable();
283         return true;
284 }
285
286
287 //      \83\8a\83Z\83b\83g
288 void OPN::Reset()
289 {
290         int i;
291         for (i=0x20; i<0x28; i++) SetReg(i, 0);
292         for (i=0x30; i<0xc0; i++) SetReg(i, 0);
293         OPNBase::Reset();
294         ch[0].Reset();
295         ch[1].Reset();
296         ch[2].Reset();
297 }
298
299
300 //      \83\8c\83W\83X\83^\93Ç\82Ý\8d\9e\82Ý
301 uint OPN::GetReg(uint addr)
302 {
303         if (addr < 0x10)
304                 return psg.GetReg(addr);
305         else
306                 return 0;
307 }
308
309
310 //      \83\8c\83W\83X\83^\83A\83\8c\83C\82É\83f\81[\83^\82ð\90Ý\92è
311 void OPN::SetReg(uint addr, uint data)
312 {
313 //      LOG2("reg[%.2x] <- %.2x\n", addr, data);
314         if (addr >= 0x100)
315                 return;
316         
317         int c = addr & 3;
318
319         switch (addr)
320         {
321         case  0: case  1: case  2: case  3: case  4: case  5: case  6: case  7:
322         case  8: case  9: case 10: case 11: case 12: case 13: case 14: case 15:
323                 psg.SetReg(addr, data);
324                 break;
325
326         case 0x24: case 0x25:
327                 SetTimerA(addr, data);
328                 break;
329
330         case 0x26:
331                 SetTimerB(data);
332                 break;
333
334         case 0x27:
335                 SetTimerControl(data);
336                 break;
337         
338         case 0x28:              // Key On/Off
339                 if ((data & 3) < 3)     ch[data & 3].KeyControl(data >> 4);
340                 break;
341
342         case 0x2d: case 0x2e: case 0x2f:
343                 SetPrescaler(addr-0x2d);
344                 break;
345
346         // F-Number
347         case 0xa0: case 0xa1: case 0xa2:
348                 if (c <= 2)     fnum[c] = data + fnum2[c] * 0x100; 
349                 break;
350         
351         case 0xa4: case 0xa5: case 0xa6:
352                 fnum2[c] = uint8(data);
353                 break;
354
355         case 0xa8: case 0xa9: case 0xaa:
356                 if(c < 3) fnum3[c] = data + fnum2[c+3] * 0x100; 
357                 break;
358         
359         case 0xac: case 0xad: case 0xae:
360                 fnum2[c+3] = uint8(data);
361                 break;
362         
363         case 0xb0:      case 0xb1:  case 0xb2:
364                 ch[c].SetFB((data >> 3) & 7);
365                 ch[c].SetAlgorithm(data & 7);
366                 break;
367                 
368         default:
369                 if (c < 3)
370                 {
371                         if ((addr & 0xf0) == 0x60)
372                                 data &= 0x1f;
373                         OPNBase::SetParameter(&ch[c], addr, data);
374                 }
375                 break;
376         }
377 }
378
379 //      \83X\83e\81[\83^\83X\83t\83\89\83O\90Ý\92è
380 void OPN::SetStatus(uint bits)
381 {
382         if (!(status & bits))
383         {
384                 status |= bits;
385                 Intr(true);
386         }
387 }
388
389 void OPN::ResetStatus(uint bit)
390 {
391         status &= ~bit;
392         if (!status)
393                 Intr(false);
394 }
395
396 //      \83}\83X\83N\90Ý\92è
397 void OPN::SetChannelMask(uint mask)
398 {
399         for (int i=0; i<3; i++)
400                 ch[i].Mute(!!(mask & (1 << i)));
401         psg.SetChannelMask(mask >> 6);
402 }
403
404
405 //      \8d\87\90¬(2ch)
406 void OPN::Mix(Sample* buffer, int nsamples)
407 {
408 #define IStoSample(s)   ((Limit(s, 0x7fff, -0x8000) * fmvolume) >> 14)
409         
410         psg.Mix(buffer, nsamples);
411         
412         // Set F-Number
413         ch[0].SetFNum(fnum[0]);
414         ch[1].SetFNum(fnum[1]);
415         if (!(regtc & 0xc0))
416                 ch[2].SetFNum(fnum[2]);
417         else
418         {       // \8cø\89Ê\89¹
419                 ch[2].op[0].SetFNum(fnum3[1]);
420                 ch[2].op[1].SetFNum(fnum3[2]);
421                 ch[2].op[2].SetFNum(fnum3[0]);
422                 ch[2].op[3].SetFNum(fnum[2]);
423         }
424         
425         int actch = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
426         if (actch & 0x15)
427         {
428                 Sample* limit = buffer + nsamples * 2;
429                 for (Sample* dest = buffer; dest < limit; dest+=2)
430                 {
431                         ISample s = 0;
432                         if (actch & 0x01) s  = ch[0].Calc();
433                         if (actch & 0x04) s += ch[1].Calc();
434                         if (actch & 0x10) s += ch[2].Calc();
435                         s = IStoSample(s);
436                         StoreSample(dest[0], s);
437                         StoreSample(dest[1], s);
438                 }
439         }
440 #undef IStoSample
441 }
442
443 // ---------------------------------------------------------------------------
444 //      \83X\83e\81[\83g\83Z\81[\83u
445 //
446 #define OPN_STATE_VERSION       1
447
448 void OPN::SaveState(void *f)
449 {
450         FILEIO *state_fio = (FILEIO *)f;
451         
452         state_fio->FputUint32(OPN_STATE_VERSION);
453         
454         OPNBase::SaveState(f);
455         state_fio->Fwrite(fnum, sizeof(fnum), 1);
456         state_fio->Fwrite(fnum3, sizeof(fnum3), 1);
457         state_fio->Fwrite(fnum2, sizeof(fnum2), 1);
458         for(int i = 0; i < 3; i++) {
459                 ch[i].SaveState(f);
460         }
461 }
462
463 bool OPN::LoadState(void *f)
464 {
465         FILEIO *state_fio = (FILEIO *)f;
466         
467         if(state_fio->FgetUint32() != OPN_STATE_VERSION) {
468                 return false;
469         }
470         if(!OPNBase::LoadState(f)) {
471                 return false;
472         }
473         state_fio->Fread(fnum, sizeof(fnum), 1);
474         state_fio->Fread(fnum3, sizeof(fnum3), 1);
475         state_fio->Fread(fnum2, sizeof(fnum2), 1);
476         for(int i = 0; i < 3; i++) {
477                 if(!ch[i].LoadState(f)) {
478                         return false;
479                 }
480         }
481         return true;
482 }
483
484 #endif // BUILD_OPN
485
486 // ---------------------------------------------------------------------------
487 //      YM2608/2610 common part
488 // ---------------------------------------------------------------------------
489
490 #if defined(BUILD_OPNA) || defined(BUILD_OPNB)
491
492 int OPNABase::amtable[FM_LFOENTS] = { -1, };
493 int OPNABase::pmtable[FM_LFOENTS];
494
495 int32 OPNABase::tltable[FM_TLENTS+FM_TLPOS];
496 bool OPNABase::tablehasmade = false;
497
498 OPNABase::OPNABase()
499 {
500         adpcmbuf = 0;
501         memaddr = 0;
502         startaddr = 0;
503         deltan = 256;
504
505         adpcmvol = 0;
506         control2 = 0;
507
508         MakeTable2();
509         BuildLFOTable();
510         for (int i=0; i<6; i++)
511         {
512                 ch[i].SetChip(&chip);
513                 ch[i].SetType(typeN);
514         }
515 }
516
517 OPNABase::~OPNABase()
518 {
519 }
520
521 // ---------------------------------------------------------------------------
522 //      \8f\89\8aú\89»
523 //
524 bool OPNABase::Init(uint c, uint r, bool)
525 {
526         RebuildTimeTable();
527         
528         Reset();
529
530         SetVolumeFM(0);
531         SetVolumePSG(0);
532         SetChannelMask(0);
533         return true;
534 }
535
536 // ---------------------------------------------------------------------------
537 //      \83e\81[\83u\83\8b\8dì\90¬
538 //
539 void OPNABase::MakeTable2()
540 {
541         if (!tablehasmade)
542         {
543                 for (int i=-FM_TLPOS; i<FM_TLENTS; i++)
544                 {
545                         tltable[i+FM_TLPOS] = uint(65536. * pow(2.0, i * -16. / FM_TLENTS))-1;
546                 }
547
548                 tablehasmade = true;
549         }
550 }
551
552 // ---------------------------------------------------------------------------
553 //      \83\8a\83Z\83b\83g
554 //
555 void OPNABase::Reset()
556 {
557         int i;
558         
559         OPNBase::Reset();
560         for (i=0x20; i<0x28; i++) SetReg(i, 0);
561         for (i=0x30; i<0xc0; i++) SetReg(i, 0);
562         for (i=0x130; i<0x1c0; i++) SetReg(i, 0);
563         for (i=0x100; i<0x110; i++) SetReg(i, 0);
564         for (i=0x10; i<0x20; i++) SetReg(i, 0);
565         for (i=0; i<6; i++)
566         {
567                 pan[i] = 3;
568                 ch[i].Reset();
569         }
570         
571         stmask = ~0x1c;
572         statusnext = 0;
573         memaddr = 0;
574         adpcmlevel = 0;
575         adpcmd = 127;
576         adpcmx = 0;
577         adpcmreadbuf = 0;
578         apout0 = apout1 = adpcmout = 0;
579         lfocount = 0;
580         adpcmplay = false;
581         adplc = 0;
582         adpld = 0x100;
583         status = 0;
584         UpdateStatus();
585 }
586
587 // ---------------------------------------------------------------------------
588 //      \83T\83\93\83v\83\8a\83\93\83O\83\8c\81[\83g\95Ï\8dX
589 //
590 bool OPNABase::SetRate(uint c, uint r, bool)
591 {
592         c /= 2;         // \8f]\97\88\94Å\82Æ\82Ì\8cÝ\8a·\90«\82ð\8fd\8e\8b\82µ\82½\82¯\82è\82á\83R\83\81\83\93\83g\83A\83E\83g\82µ\82æ\82¤
593         
594         OPNBase::Init(c, r);
595
596         adplbase = int(8192. * (clock/72.) / r);
597         adpld = deltan * adplbase >> 16;      
598                 
599         RebuildTimeTable();
600
601         lfodcount = reg22 & 0x08 ? lfotable[reg22 & 7] : 0;
602         return true;
603 }
604
605
606 // ---------------------------------------------------------------------------
607 //      \83`\83\83\83\93\83l\83\8b\83}\83X\83N\82Ì\90Ý\92è
608 //
609 void OPNABase::SetChannelMask(uint mask)
610 {
611         for (int i=0; i<6; i++)
612                 ch[i].Mute(!!(mask & (1 << i)));
613         psg.SetChannelMask(mask >> 6);
614         adpcmmask_ = (mask & (1 << 9)) != 0;
615         rhythmmask_ = (mask >> 10) & ((1 << 6) - 1);
616 }
617
618 // ---------------------------------------------------------------------------
619 //      \83\8c\83W\83X\83^\83A\83\8c\83C\82É\83f\81[\83^\82ð\90Ý\92è
620 //
621 void OPNABase::SetReg(uint addr, uint data)
622 {
623         int     c = addr & 3;
624         switch (addr)
625         {
626                 uint modified;
627
628         // Timer -----------------------------------------------------------------
629                 case 0x24: case 0x25:
630                         SetTimerA(addr, data);
631                         break;
632
633                 case 0x26:
634                         SetTimerB(data);
635                         break;
636
637                 case 0x27:
638                         SetTimerControl(data);
639                         break;
640
641         // Misc ------------------------------------------------------------------
642         case 0x28:              // Key On/Off
643                 if ((data & 3) < 3)
644                 {
645                         c = (data & 3) + (data & 4 ? 3 : 0);
646                         ch[c].KeyControl(data >> 4);
647                 }
648                 break;
649
650         // Status Mask -----------------------------------------------------------
651         case 0x29:
652                 reg29 = data;
653 //              UpdateStatus(); //?
654                 break;
655         
656         // Prescaler -------------------------------------------------------------
657         case 0x2d: case 0x2e: case 0x2f:
658                 SetPrescaler(addr-0x2d);
659                 break;
660         
661         // F-Number --------------------------------------------------------------
662         case 0x1a0:     case 0x1a1: case 0x1a2:
663                 c += 3;
664         case 0xa0:      case 0xa1: case 0xa2:
665                 fnum[c] = data + fnum2[c] * 0x100;
666                 ch[c].SetFNum(fnum[c]);
667                 break;
668
669         case 0x1a4:     case 0x1a5: case 0x1a6:
670                 c += 3;
671         case 0xa4 : case 0xa5: case 0xa6:
672                 fnum2[c] = uint8(data);
673                 break;
674
675         case 0xa8:      case 0xa9: case 0xaa:
676                 fnum3[c] = data + fnum2[c+6] * 0x100;
677                 break;
678
679         case 0xac : case 0xad: case 0xae:
680                 fnum2[c+6] = uint8(data);
681                 break;
682                 
683         // Algorithm -------------------------------------------------------------
684         
685         case 0x1b0:     case 0x1b1:  case 0x1b2:
686                 c += 3;
687         case 0xb0:      case 0xb1:  case 0xb2:
688                 ch[c].SetFB((data >> 3) & 7);
689                 ch[c].SetAlgorithm(data & 7);
690                 break;
691         
692         case 0x1b4: case 0x1b5: case 0x1b6:
693                 c += 3;
694         case 0xb4: case 0xb5: case 0xb6:
695                 pan[c] = (data >> 6) & 3;
696                 ch[c].SetMS(data);
697                 break;
698
699         // LFO -------------------------------------------------------------------
700         case 0x22:
701                 modified = reg22 ^ data;
702                 reg22 = data;
703                 if (modified & 0x8)
704                         lfocount = 0;
705                 lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0;
706                 break;
707
708         // PSG -------------------------------------------------------------------
709         case  0: case  1: case  2: case  3: case  4: case  5: case  6: case  7:
710         case  8: case  9: case 10: case 11: case 12: case 13: case 14: case 15:
711                 psg.SetReg(addr, data);
712                 break;
713
714         // \89¹\90F ------------------------------------------------------------------
715         default:
716                 if (c < 3)
717                 {
718                         if (addr & 0x100)
719                                 c += 3;
720                         OPNBase::SetParameter(&ch[c], addr, data);
721                 }
722                 break;
723         }
724 }
725
726 // ---------------------------------------------------------------------------
727 //      ADPCM B
728 //
729 void OPNABase::SetADPCMBReg(uint addr, uint data)
730 {
731         switch (addr)
732         {
733         case 0x00:              // Control Register 1
734                 if ((data & 0x80) && !adpcmplay)
735                 {
736                         adpcmplay = true;
737                         memaddr = startaddr;
738                         adpcmx = 0, adpcmd = 127;
739                         adplc = 0;
740                 }
741                 if (data & 1)
742                 {
743                         adpcmplay = false;
744                 }
745                 control1 = data;
746                 break;
747
748         case 0x01:              // Control Register 2
749                 control2 = data;
750                 granuality = control2 & 2 ? 1 : 4;
751                 break;
752
753         case 0x02:              // Start Address L
754         case 0x03:              // Start Address H
755                 adpcmreg[addr - 0x02 + 0] = data;
756                 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 6;
757                 memaddr = startaddr;
758 //              LOG1("  startaddr %.6x", startaddr);
759                 break;
760
761         case 0x04:              // Stop Address L
762         case 0x05:              // Stop Address H
763                 adpcmreg[addr - 0x04 + 2] = data;
764                 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 6;
765 //              LOG1("  stopaddr %.6x", stopaddr);
766                 break;
767
768         case 0x08:              // ADPCM data
769                 if ((control1 & 0x60) == 0x60)
770                 {
771 //                      LOG2("  Wr [0x%.5x] = %.2x", memaddr, data);
772                         WriteRAM(data);
773                 }
774                 break;
775
776         case 0x09:              // delta-N L
777         case 0x0a:              // delta-N H
778                 adpcmreg[addr - 0x09 + 4] = data;
779                 deltan = adpcmreg[5]*256+adpcmreg[4];
780                 deltan = Max(256, deltan);
781                 adpld = deltan * adplbase >> 16;
782                 break;
783
784         case 0x0b:              // Level Control
785                 adpcmlevel = data; 
786                 adpcmvolume = (adpcmvol * adpcmlevel) >> 12;
787                 break;
788
789         case 0x0c:              // Limit Address L
790         case 0x0d:              // Limit Address H
791                 adpcmreg[addr - 0x0c + 6] = data;
792                 limitaddr = (adpcmreg[7]*256+adpcmreg[6] + 1) << 6;
793 //              LOG1("  limitaddr %.6x", limitaddr);
794                 break;
795
796         case 0x10:              // Flag Control
797                 if (data & 0x80)
798                 {
799                         status = 0;
800                         UpdateStatus();
801                 }
802                 else
803                 {
804                         stmask = ~(data & 0x1f);
805 //                      UpdateStatus();                                 //???
806                 }
807                 break;
808         }
809 }       
810
811
812 // ---------------------------------------------------------------------------
813 //      \83\8c\83W\83X\83^\8eæ\93¾
814 //
815 uint OPNA::GetReg(uint addr)
816 {
817         if (addr < 0x10)
818                 return psg.GetReg(addr);
819
820         if (addr == 0x108)
821         {
822 //              LOG1("%d:reg[108] ->   ", Diag::GetCPUTick());
823                 
824                 uint data = adpcmreadbuf & 0xff;
825                 adpcmreadbuf >>= 8;
826                 if ((control1 & 0x60) == 0x20)
827                 {
828                         adpcmreadbuf |= ReadRAM() << 8;
829 //                      LOG2("Rd [0x%.6x:%.2x] ", memaddr, adpcmreadbuf >> 8);
830                 }
831 //              LOG0("%.2x\n");
832                 return data;
833         }
834         
835         if (addr == 0xff)
836                 return 1;
837         
838         return 0;
839 }
840
841
842
843
844 // ---------------------------------------------------------------------------
845 //      \83X\83e\81[\83^\83X\83t\83\89\83O\90Ý\92è
846 //
847 void OPNABase::SetStatus(uint bits)
848 {
849         if (!(status & bits))
850         {
851 //              LOG2("SetStatus(%.2x %.2x)\n", bits, stmask);
852                 status |= bits & stmask;
853                 UpdateStatus();
854         }
855 //      else
856 //              LOG1("SetStatus(%.2x) - ignored\n", bits);
857 }
858
859 void OPNABase::ResetStatus(uint bits)
860 {
861         status &= ~bits;
862 //      LOG1("ResetStatus(%.2x)\n", bits);
863         UpdateStatus();
864 }
865
866 inline void OPNABase::UpdateStatus()
867 {
868 //      LOG2("%d:INT = %d\n", Diag::GetCPUTick(), (status & stmask & reg29) != 0);
869         Intr((status & stmask & reg29) != 0);
870 }
871
872 // ---------------------------------------------------------------------------
873 //      ADPCM RAM \82Ö\82Ì\8f\91\8d\9e\82Ý\91\80\8dì
874 //
875 void OPNABase::WriteRAM(uint data)
876 {
877 #ifndef NO_BITTYPE_EMULATION
878         if (!(control2 & 2))
879         {
880                 // 1 bit mode
881                 adpcmbuf[(memaddr >> 4) & 0x3ffff] = data;
882                 memaddr += 16;
883         }
884         else
885         {
886                 // 8 bit mode
887                 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
888                 uint bank = (memaddr >> 1) & 7;
889                 uint8 mask = 1 << bank;
890                 data <<= bank;
891
892                 p[0x00000] = (p[0x00000] & ~mask) | (uint8(data) & mask); data >>= 1;
893                 p[0x08000] = (p[0x08000] & ~mask) | (uint8(data) & mask); data >>= 1;
894                 p[0x10000] = (p[0x10000] & ~mask) | (uint8(data) & mask); data >>= 1;
895                 p[0x18000] = (p[0x18000] & ~mask) | (uint8(data) & mask); data >>= 1;
896                 p[0x20000] = (p[0x20000] & ~mask) | (uint8(data) & mask); data >>= 1;
897                 p[0x28000] = (p[0x28000] & ~mask) | (uint8(data) & mask); data >>= 1;
898                 p[0x30000] = (p[0x30000] & ~mask) | (uint8(data) & mask); data >>= 1;
899                 p[0x38000] = (p[0x38000] & ~mask) | (uint8(data) & mask);
900                 memaddr += 2;
901         }
902 #else
903         adpcmbuf[(memaddr >> granuality) & 0x3ffff] = data;
904         memaddr += 1 << granuality;
905 #endif
906
907         if (memaddr == stopaddr)
908         {
909                 SetStatus(4);
910                 statusnext = 0x04;      // EOS
911                 memaddr &= 0x3fffff;
912         }
913         if (memaddr == limitaddr)
914         {
915 //              LOG1("Limit ! (%.8x)\n", limitaddr);
916                 memaddr = 0;
917         }
918         SetStatus(8);
919 }
920
921 // ---------------------------------------------------------------------------
922 //      ADPCM RAM \82©\82ç\82Ì\93Ç\82Ý\8d\9e\82Ý\91\80\8dì
923 //
924 uint OPNABase::ReadRAM()
925 {
926         uint data;
927 #ifndef NO_BITTYPE_EMULATION
928         if (!(control2 & 2))
929         {
930                 // 1 bit mode
931                 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
932                 memaddr += 16;
933         }
934         else
935         {
936                 // 8 bit mode
937                 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
938                 uint bank = (memaddr >> 1) & 7;
939                 uint8 mask = 1 << bank;
940
941                 data =            (p[0x38000] & mask);
942                 data = data * 2 + (p[0x30000] & mask);
943                 data = data * 2 + (p[0x28000] & mask);
944                 data = data * 2 + (p[0x20000] & mask);
945                 data = data * 2 + (p[0x18000] & mask);
946                 data = data * 2 + (p[0x10000] & mask);
947                 data = data * 2 + (p[0x08000] & mask);
948                 data = data * 2 + (p[0x00000] & mask);
949                 data >>= bank;
950                 memaddr += 2;
951         }
952 #else
953         data = adpcmbuf[(memaddr >> granuality) & 0x3ffff];
954         memaddr += 1 << granuality;
955 #endif
956         if (memaddr == stopaddr)
957         {
958                 SetStatus(4);
959                 statusnext = 0x04;      // EOS
960                 memaddr &= 0x3fffff;
961         }
962         if (memaddr == limitaddr)
963         {
964 //              LOG1("Limit ! (%.8x)\n", limitaddr);
965                 memaddr = 0;
966         }
967         if (memaddr < stopaddr)
968                 SetStatus(8);
969         return data;
970 }
971
972
973 inline int OPNABase::DecodeADPCMBSample(uint data)
974 {
975         static const int table1[16] =
976         {
977                   1,   3,   5,   7,   9,  11,  13,  15,
978                  -1,  -3,  -5,  -7,  -9, -11, -13, -15,
979         };
980         static const int table2[16] =
981         {
982                  57,  57,  57,  57,  77, 102, 128, 153,
983                  57,  57,  57,  57,  77, 102, 128, 153,
984         };
985         adpcmx = Limit(adpcmx + table1[data] * adpcmd / 8, 32767, -32768);
986         adpcmd = Limit(adpcmd * table2[data] / 64, 24576, 127);
987         return adpcmx;
988 }       
989
990
991 // ---------------------------------------------------------------------------
992 //      ADPCM RAM \82©\82ç\82Ì nibble \93Ç\82Ý\8d\9e\82Ý\8by\82Ñ ADPCM \93W\8aJ
993 //
994 int OPNABase::ReadRAMN()
995 {
996         uint data;
997         if (granuality > 0)
998         {
999 #ifndef NO_BITTYPE_EMULATION
1000                 if (!(control2 & 2))
1001                 {
1002                         data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
1003                         memaddr += 8;
1004                         if (memaddr & 8)
1005                                 return DecodeADPCMBSample(data >> 4);
1006                         data &= 0x0f;
1007                 }
1008                 else
1009                 {
1010                         uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff] + ((~memaddr & 1) << 17);
1011                         uint bank = (memaddr >> 1) & 7;
1012                         uint8 mask = 1 << bank;
1013
1014                         data =            (p[0x18000] & mask);
1015                         data = data * 2 + (p[0x10000] & mask);
1016                         data = data * 2 + (p[0x08000] & mask);
1017                         data = data * 2 + (p[0x00000] & mask);
1018                         data >>= bank;
1019                         memaddr ++;
1020                         if (memaddr & 1)
1021                                 return DecodeADPCMBSample(data);
1022                 }
1023 #else
1024                 data = adpcmbuf[(memaddr >> granuality) & adpcmmask];
1025                 memaddr += 1 << (granuality-1);
1026                 if (memaddr & (1 << (granuality-1)))
1027                         return DecodeADPCMBSample(data >> 4);
1028                 data &= 0x0f;
1029 #endif
1030         }
1031         else
1032         {
1033                 data = adpcmbuf[(memaddr >> 1) & adpcmmask];
1034                 ++memaddr;
1035                 if (memaddr & 1)
1036                         return DecodeADPCMBSample(data >> 4);
1037                 data &= 0x0f;
1038         }
1039         
1040         DecodeADPCMBSample(data);
1041         
1042         // check
1043         if (memaddr == stopaddr)
1044         {
1045                 if (control1 & 0x10)
1046                 {
1047                         memaddr = startaddr;
1048                         data = adpcmx;
1049                         adpcmx = 0, adpcmd = 127;
1050                         return data;
1051                 }
1052                 else
1053                 {
1054                         memaddr &= adpcmmask;   //0x3fffff;
1055                         SetStatus(adpcmnotice);
1056                         adpcmplay = false;
1057                 }
1058         }
1059         
1060         if (memaddr == limitaddr)
1061                 memaddr = 0;
1062         
1063         return adpcmx;
1064 }
1065
1066 // ---------------------------------------------------------------------------
1067 //      \8ag\92£\83X\83e\81[\83^\83X\82ð\93Ç\82Ý\82±\82Þ
1068 //
1069 uint OPNABase::ReadStatusEx()
1070 {
1071         uint r = ((status | 8) & stmask) | (adpcmplay ? 0x20 : 0);
1072         status |= statusnext;
1073         statusnext = 0;
1074         return r;
1075 }
1076
1077 // ---------------------------------------------------------------------------
1078 //      ADPCM \93W\8aJ
1079 //
1080 inline void OPNABase::DecodeADPCMB()
1081 {
1082         apout0 = apout1;
1083         int n = (ReadRAMN() * adpcmvolume) >> 13;
1084         apout1 = adpcmout + n;
1085         adpcmout = n;
1086 }
1087
1088 // ---------------------------------------------------------------------------
1089 //      ADPCM \8d\87\90¬
1090 //      
1091 void OPNABase::ADPCMBMix(Sample* dest, uint count)
1092 {
1093         uint maskl = control2 & 0x80 ? -1 : 0;
1094         uint maskr = control2 & 0x40 ? -1 : 0;
1095         if (adpcmmask_)
1096         {
1097                 maskl = maskr = 0;
1098         }
1099         
1100         if (adpcmplay)
1101         {
1102 //              LOG2("ADPCM Play: %d   DeltaN: %d\n", adpld, deltan);
1103                 if (adpld <= 8192)              // fplay < fsamp
1104                 {
1105                         for (; count>0; count--)
1106                         {
1107                                 if (adplc < 0)
1108                                 {
1109                                         adplc += 8192;
1110                                         DecodeADPCMB();
1111                                         if (!adpcmplay)
1112                                                 break;
1113                                 }
1114                                 int s = (adplc * apout0 + (8192-adplc) * apout1) >> 13;
1115                                 StoreSample(dest[0], s & maskl);
1116                                 StoreSample(dest[1], s & maskr);
1117                                 dest += 2;
1118                                 adplc -= adpld;
1119                         }
1120                         for (; count>0 && apout0; count--)
1121                         {
1122                                 if (adplc < 0)
1123                                 {
1124                                         apout0 = apout1, apout1 = 0;
1125                                         adplc += 8192;
1126                                 }
1127                                 int s = (adplc * apout1) >> 13;
1128                                 StoreSample(dest[0], s & maskl);
1129                                 StoreSample(dest[1], s & maskr);
1130                                 dest += 2;
1131                                 adplc -= adpld;
1132                         }
1133                 }
1134                 else    // fplay > fsamp        (adpld = fplay/famp*8192)
1135                 {
1136                         int t = (-8192*8192)/adpld;
1137                         for (; count>0; count--)
1138                         {
1139                                 int s = apout0 * (8192+adplc);
1140                                 while (adplc < 0)
1141                                 {
1142                                         DecodeADPCMB();
1143                                         if (!adpcmplay)
1144                                                 goto stop;
1145                                         s -= apout0 * Max(adplc, t);
1146                                         adplc -= t;
1147                                 }
1148                                 adplc -= 8192;
1149                                 s >>= 13;
1150                                 StoreSample(dest[0], s & maskl);
1151                                 StoreSample(dest[1], s & maskr);
1152                                 dest += 2;
1153                         }
1154 stop:
1155                         ;
1156                 }
1157         }
1158         if (!adpcmplay)
1159         {
1160                 apout0 = apout1 = adpcmout = 0;
1161                 adplc = 0;
1162         }
1163 }
1164
1165 // ---------------------------------------------------------------------------
1166 //      \8d\87\90¬
1167 //      in:             buffer          \8d\87\90¬\90æ
1168 //                      nsamples        \8d\87\90¬\83T\83\93\83v\83\8b\90\94
1169 //
1170 void OPNABase::FMMix(Sample* buffer, int nsamples)
1171 {
1172         if (fmvolume > 0)
1173         {
1174                 // \8f\80\94õ
1175                 // Set F-Number
1176                 if (!(regtc & 0xc0))
1177                         csmch->SetFNum(fnum[csmch-ch]);
1178                 else
1179                 {
1180                         // \8cø\89Ê\89¹\83\82\81[\83h
1181                         csmch->op[0].SetFNum(fnum3[1]); csmch->op[1].SetFNum(fnum3[2]);
1182                         csmch->op[2].SetFNum(fnum3[0]); csmch->op[3].SetFNum(fnum[2]);
1183                 }
1184                 
1185                 int act = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
1186                 if (reg29 & 0x80)
1187                         act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6;
1188                 if (!(reg22 & 0x08))
1189                         act &= 0x555;
1190
1191                 if (act & 0x555)
1192                 {
1193                         Mix6(buffer, nsamples, act);
1194                 }
1195         }
1196 }
1197
1198 // ---------------------------------------------------------------------------
1199
1200 void OPNABase::MixSubSL(int activech, ISample** dest)
1201 {
1202         if (activech & 0x001) (*dest[0]  = ch[0].CalcL());
1203         if (activech & 0x004) (*dest[1] += ch[1].CalcL());
1204         if (activech & 0x010) (*dest[2] += ch[2].CalcL());
1205         if (activech & 0x040) (*dest[3] += ch[3].CalcL());
1206         if (activech & 0x100) (*dest[4] += ch[4].CalcL());
1207         if (activech & 0x400) (*dest[5] += ch[5].CalcL());
1208 }
1209
1210 inline void OPNABase::MixSubS(int activech, ISample** dest)
1211 {
1212         if (activech & 0x001) (*dest[0]  = ch[0].Calc());
1213         if (activech & 0x004) (*dest[1] += ch[1].Calc());
1214         if (activech & 0x010) (*dest[2] += ch[2].Calc());
1215         if (activech & 0x040) (*dest[3] += ch[3].Calc());
1216         if (activech & 0x100) (*dest[4] += ch[4].Calc());
1217         if (activech & 0x400) (*dest[5] += ch[5].Calc());
1218 }
1219
1220 // ---------------------------------------------------------------------------
1221
1222 void OPNABase::BuildLFOTable()
1223 {
1224         if (amtable[0] == -1)
1225         {
1226                 for (int c=0; c<256; c++)
1227                 {
1228                         int v;
1229                         if (c < 0x40)           v = c * 2 + 0x80;
1230                         else if (c < 0xc0)      v = 0x7f - (c - 0x40) * 2 + 0x80;
1231                         else                            v = (c - 0xc0) * 2;
1232                         pmtable[c] = v;
1233
1234                         if (c < 0x80)           v = 0xff - c * 2;
1235                         else                            v = (c - 0x80) * 2;
1236                         amtable[c] = v & ~3;
1237                 }
1238         }
1239 }
1240
1241 // ---------------------------------------------------------------------------
1242
1243 inline void OPNABase::LFO()
1244 {
1245 //      LOG3("%4d - %8d, %8d\n", c, lfocount, lfodcount);
1246
1247 //      Operator::SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1248 //      Operator::SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1249         chip.SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1250         chip.SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1251         lfocount += lfodcount;
1252 }
1253
1254 // ---------------------------------------------------------------------------
1255 //      \8d\87\90¬
1256 //
1257 #define IStoSample(s)   ((Limit(s, 0x7fff, -0x8000) * fmvolume) >> 14)
1258
1259 void OPNABase::Mix6(Sample* buffer, int nsamples, int activech)
1260 {
1261         // Mix
1262         ISample ibuf[4];
1263         ISample* idest[6];
1264         idest[0] = &ibuf[pan[0]];
1265         idest[1] = &ibuf[pan[1]];
1266         idest[2] = &ibuf[pan[2]];
1267         idest[3] = &ibuf[pan[3]];
1268         idest[4] = &ibuf[pan[4]];
1269         idest[5] = &ibuf[pan[5]];
1270
1271         Sample* limit = buffer + nsamples * 2;
1272         for (Sample* dest = buffer; dest < limit; dest+=2)
1273         {
1274                 ibuf[1] = ibuf[2] = ibuf[3] = 0;
1275                 if (activech & 0xaaa)
1276                         LFO(), MixSubSL(activech, idest);
1277                 else
1278                         MixSubS(activech, idest);
1279                 StoreSample(dest[0], IStoSample(ibuf[2] + ibuf[3]));
1280                 StoreSample(dest[1], IStoSample(ibuf[1] + ibuf[3]));
1281         }
1282 }
1283
1284 // ---------------------------------------------------------------------------
1285 //      \83X\83e\81[\83g\83Z\81[\83u
1286 //
1287 #define OPNA_BASE_STATE_VERSION 1
1288
1289 void OPNABase::SaveState(void *f)
1290 {
1291         FILEIO *state_fio = (FILEIO *)f;
1292         
1293         state_fio->FputUint32(OPNA_BASE_STATE_VERSION);
1294         
1295         OPNBase::SaveState(f);
1296         state_fio->Fwrite(pan, sizeof(pan), 1);
1297         state_fio->Fwrite(fnum2, sizeof(fnum2), 1);
1298         state_fio->FputUint8(reg22);
1299         state_fio->FputUint32(reg29);
1300         state_fio->FputUint32(stmask);
1301         state_fio->FputUint32(statusnext);
1302         state_fio->FputUint32(lfocount);
1303         state_fio->FputUint32(lfodcount);
1304         state_fio->Fwrite(fnum, sizeof(fnum), 1);
1305         state_fio->Fwrite(fnum3, sizeof(fnum3), 1);
1306         state_fio->Fwrite(adpcmbuf, 0x40000, 1);
1307         state_fio->FputUint32(adpcmmask);
1308         state_fio->FputUint32(adpcmnotice);
1309         state_fio->FputUint32(startaddr);
1310         state_fio->FputUint32(stopaddr);
1311         state_fio->FputUint32(memaddr);
1312         state_fio->FputUint32(limitaddr);
1313         state_fio->FputInt32(adpcmlevel);
1314         state_fio->FputInt32(adpcmvolume);
1315         state_fio->FputInt32(adpcmvol);
1316         state_fio->FputUint32(deltan);
1317         state_fio->FputInt32(adplc);
1318         state_fio->FputInt32(adpld);
1319         state_fio->FputUint32(adplbase);
1320         state_fio->FputInt32(adpcmx);
1321         state_fio->FputInt32(adpcmd);
1322         state_fio->FputInt32(adpcmout);
1323         state_fio->FputInt32(apout0);
1324         state_fio->FputInt32(apout1);
1325         state_fio->FputUint32(adpcmreadbuf);
1326         state_fio->FputBool(adpcmplay);
1327         state_fio->FputInt8(granuality);
1328         state_fio->FputBool(adpcmmask_);
1329         state_fio->FputUint8(control1);
1330         state_fio->FputUint8(control2);
1331         state_fio->Fwrite(adpcmreg, sizeof(adpcmreg), 1);
1332         state_fio->FputInt32(rhythmmask_);
1333         for(int i = 0; i < 6; i++) {
1334                 ch[i].SaveState(f);
1335         }
1336 }
1337
1338 bool OPNABase::LoadState(void *f)
1339 {
1340         FILEIO *state_fio = (FILEIO *)f;
1341         
1342         if(state_fio->FgetUint32() != OPNA_BASE_STATE_VERSION) {
1343                 return false;
1344         }
1345         if(!OPNBase::LoadState(f)) {
1346                 return false;
1347         }
1348         state_fio->Fread(pan, sizeof(pan), 1);
1349         state_fio->Fread(fnum2, sizeof(fnum2), 1);
1350         reg22 = state_fio->FgetUint8();
1351         reg29 = state_fio->FgetUint32();
1352         stmask = state_fio->FgetUint32();
1353         statusnext = state_fio->FgetUint32();
1354         lfocount = state_fio->FgetUint32();
1355         lfodcount = state_fio->FgetUint32();
1356         state_fio->Fread(fnum, sizeof(fnum), 1);
1357         state_fio->Fread(fnum3, sizeof(fnum3), 1);
1358         state_fio->Fread(adpcmbuf, 0x40000, 1);
1359         adpcmmask = state_fio->FgetUint32();
1360         adpcmnotice = state_fio->FgetUint32();
1361         startaddr = state_fio->FgetUint32();
1362         stopaddr = state_fio->FgetUint32();
1363         memaddr = state_fio->FgetUint32();
1364         limitaddr = state_fio->FgetUint32();
1365         adpcmlevel = state_fio->FgetInt32();
1366         adpcmvolume = state_fio->FgetInt32();
1367         adpcmvol = state_fio->FgetInt32();
1368         deltan = state_fio->FgetUint32();
1369         adplc = state_fio->FgetInt32();
1370         adpld = state_fio->FgetInt32();
1371         adplbase = state_fio->FgetUint32();
1372         adpcmx = state_fio->FgetInt32();
1373         adpcmd = state_fio->FgetInt32();
1374         adpcmout = state_fio->FgetInt32();
1375         apout0 = state_fio->FgetInt32();
1376         apout1 = state_fio->FgetInt32();
1377         adpcmreadbuf = state_fio->FgetUint32();
1378         adpcmplay = state_fio->FgetBool();
1379         granuality = state_fio->FgetInt8();
1380         adpcmmask_ = state_fio->FgetBool();
1381         control1 = state_fio->FgetUint8();
1382         control2 = state_fio->FgetUint8();
1383         state_fio->Fread(adpcmreg, sizeof(adpcmreg), 1);
1384         rhythmmask_ = state_fio->FgetInt32();
1385         for(int i = 0; i < 6; i++) {
1386                 if(!ch[i].LoadState(f)) {
1387                         return false;
1388                 }
1389         }
1390         return true;
1391 }
1392
1393 #endif // defined(BUILD_OPNA) || defined(BUILD_OPNB)
1394
1395 // ---------------------------------------------------------------------------
1396 //      YM2608(OPNA)
1397 // ---------------------------------------------------------------------------
1398
1399 #ifdef BUILD_OPNA
1400
1401 // ---------------------------------------------------------------------------
1402 //      \8d\\92z
1403 //
1404 OPNA::OPNA()
1405 {
1406         for (int i=0; i<6; i++)
1407         {
1408                 rhythm[i].sample = 0;
1409                 rhythm[i].pos = 0;
1410                 rhythm[i].size = 0;
1411                 rhythm[i].volume = 0;
1412                 rhythm[i].level = 0;
1413                 rhythm[i].pan = 0;
1414         }
1415         rhythmtvol = 0;
1416         adpcmmask = 0x3ffff;
1417         adpcmnotice = 4;
1418         csmch = &ch[2];
1419 }
1420
1421 // ---------------------------------------------------------------------------
1422
1423 OPNA::~OPNA()
1424 {
1425         delete[] adpcmbuf;
1426         for (int i=0; i<6; i++)
1427                 delete[] rhythm[i].sample;
1428 }
1429
1430
1431
1432 // ---------------------------------------------------------------------------
1433 //      \8f\89\8aú\89»
1434 //
1435 bool OPNA::Init(uint c, uint r, bool ipflag, const _TCHAR* path)
1436 {
1437         rate = 8000;
1438         LoadRhythmSample(path);
1439         
1440         if (!adpcmbuf)
1441                 adpcmbuf = new uint8[0x40000];
1442         if (!adpcmbuf)
1443                 return false;
1444
1445         if (!SetRate(c, r, ipflag))
1446                 return false;
1447         if (!OPNABase::Init(c, r, ipflag))
1448                 return false;
1449         
1450         Reset();
1451
1452         SetVolumeADPCM(0);
1453         SetVolumeRhythmTotal(0);
1454         for (int i=0; i<6; i++)
1455                 SetVolumeRhythm(i, 0);
1456         return true;
1457 }
1458
1459 // ---------------------------------------------------------------------------
1460 //      \83\8a\83Z\83b\83g
1461 //
1462 void OPNA::Reset()
1463 {
1464         reg29 = 0x1f;
1465         rhythmkey = 0;
1466         rhythmtl = 0;
1467         limitaddr = 0x3ffff;
1468         OPNABase::Reset();
1469 }
1470
1471 // ---------------------------------------------------------------------------
1472 //      \83T\83\93\83v\83\8a\83\93\83O\83\8c\81[\83g\95Ï\8dX
1473 //
1474 bool OPNA::SetRate(uint c, uint r, bool ipflag)
1475 {
1476         if (!OPNABase::SetRate(c, r, ipflag))
1477                 return false;
1478
1479         for (int i=0; i<6; i++)
1480         {
1481                 rhythm[i].step = rhythm[i].rate * 1024 / r;
1482         }
1483         return true;
1484 }
1485
1486
1487 // ---------------------------------------------------------------------------
1488 //      \83\8a\83Y\83\80\89¹\82ð\93Ç\82Ý\82±\82Þ
1489 //
1490 bool OPNA::LoadRhythmSample(const _TCHAR* path)
1491 {
1492         static const _TCHAR* rhythmname[6] =
1493         {
1494                 _T("BD"), _T("SD"), _T("TOP"), _T("HH"), _T("TOM"), _T("RIM"),
1495         };
1496
1497         int i;
1498         for (i=0; i<6; i++)
1499                 rhythm[i].pos = ~0;
1500
1501         for (i=0; i<6; i++)
1502         {
1503                 FILEIO file;
1504                 uint32 fsize;
1505                 _TCHAR buf[MAX_PATH] = _T("");
1506                 if (path)
1507                         _tcsncpy(buf, path, MAX_PATH);
1508                 _tcsncat(buf, _T("2608_"), MAX_PATH);
1509                 _tcsncat(buf, rhythmname[i], MAX_PATH);
1510                 _tcsncat(buf, _T(".WAV"), MAX_PATH);
1511
1512                 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1513                 {
1514                         if (i != 5)
1515                                 break;
1516                         if (path)
1517                                 _tcsncpy(buf, path, MAX_PATH);
1518                         _tcsncpy(buf, _T("2608_RYM.WAV"), MAX_PATH);
1519                         if (!file.Fopen(buf, FILEIO_READ_BINARY))
1520                                 break;
1521                 }
1522                 
1523                 struct
1524                 {
1525                         uint32 chunksize;
1526                         uint16 tag;
1527                         uint16 nch;
1528                         uint32 rate;
1529                         uint32 avgbytes;
1530                         uint16 align;
1531                         uint16 bps;
1532                         uint16 size;
1533                 } whdr;
1534
1535                 file.Fseek(0x10, FILEIO_SEEK_SET);
1536                 file.Fread(&whdr, sizeof(whdr), 1);
1537                 
1538                 uint8 subchunkname[4];
1539                 fsize = 4 + whdr.chunksize - sizeof(whdr);
1540                 do 
1541                 {
1542                         file.Fseek(fsize, FILEIO_SEEK_CUR);
1543                         file.Fread(&subchunkname, 4, 1);
1544                         file.Fread(&fsize, 4, 1);
1545                 } while (memcmp("data", subchunkname, 4));
1546
1547                 fsize /= 2;
1548                 if (fsize >= 0x100000 || whdr.tag != 1 || whdr.nch != 1)
1549                         break;
1550                 fsize = Max(fsize, (1<<31)/1024);
1551                 
1552                 delete rhythm[i].sample;
1553                 rhythm[i].sample = new int16[fsize];
1554                 if (!rhythm[i].sample)
1555                         break;
1556                 
1557                 file.Fread(rhythm[i].sample, fsize * 2, 1);
1558                 
1559                 rhythm[i].rate = whdr.rate;
1560                 rhythm[i].step = rhythm[i].rate * 1024 / rate;
1561                 rhythm[i].pos = rhythm[i].size = fsize * 1024;
1562         }
1563         if (i != 6)
1564         {
1565                 for (i=0; i<6; i++)
1566                 {
1567                         delete[] rhythm[i].sample;
1568                         rhythm[i].sample = 0;
1569                 }
1570                 return false;
1571         }
1572         return true;
1573 }
1574
1575
1576
1577 // ---------------------------------------------------------------------------
1578 //      \83\8c\83W\83X\83^\83A\83\8c\83C\82É\83f\81[\83^\82ð\90Ý\92è
1579 //
1580 void OPNA::SetReg(uint addr, uint data)
1581 {
1582         addr &= 0x1ff;
1583
1584         switch (addr)
1585         {
1586         case 0x29:
1587                 reg29 = data;
1588 //              UpdateStatus(); //?
1589                 break;
1590         
1591         // Rhythm ----------------------------------------------------------------
1592         case 0x10:                      // DM/KEYON
1593                 if (!(data & 0x80))  // KEY ON
1594                 {
1595                         rhythmkey |= data & 0x3f;
1596                         if (data & 0x01) rhythm[0].pos = 0;
1597                         if (data & 0x02) rhythm[1].pos = 0;
1598                         if (data & 0x04) rhythm[2].pos = 0;
1599                         if (data & 0x08) rhythm[3].pos = 0;
1600                         if (data & 0x10) rhythm[4].pos = 0;
1601                         if (data & 0x20) rhythm[5].pos = 0;
1602                 }
1603                 else
1604                 {                                       // DUMP
1605                         rhythmkey &= ~data;
1606                 }
1607                 break;
1608
1609         case 0x11:
1610                 rhythmtl = ~data & 63;
1611                 break;
1612
1613         case 0x18:              // Bass Drum
1614         case 0x19:              // Snare Drum
1615         case 0x1a:              // Top Cymbal
1616         case 0x1b:              // Hihat
1617         case 0x1c:              // Tom-tom
1618         case 0x1d:              // Rim shot
1619                 rhythm[addr & 7].pan   = (data >> 6) & 3;
1620                 rhythm[addr & 7].level = ~data & 31;
1621                 break;
1622
1623         case 0x100: case 0x101:
1624         case 0x102: case 0x103:
1625         case 0x104: case 0x105:
1626         case 0x108:     case 0x109:
1627         case 0x10a:     case 0x10b:
1628         case 0x10c:     case 0x10d:
1629         case 0x110:
1630                 OPNABase::SetADPCMBReg(addr - 0x100, data);
1631                 break;
1632
1633         default:
1634                 OPNABase::SetReg(addr, data);
1635                 break;
1636         }
1637 }
1638
1639
1640 // ---------------------------------------------------------------------------
1641 //      \83\8a\83Y\83\80\8d\87\90¬
1642 //
1643 void OPNA::RhythmMix(Sample* buffer, uint count)
1644 {
1645         if (rhythmtvol < 128 && rhythm[0].sample && (rhythmkey & 0x3f))
1646         {
1647                 Sample* limit = buffer + count * 2;
1648                 for (int i=0; i<6; i++)
1649                 {
1650                         Rhythm& r = rhythm[i];
1651                         if ((rhythmkey & (1 << i)) && r.level < 128)
1652                         {
1653                                 int db = Limit(rhythmtl+rhythmtvol+r.level+r.volume, 127, -31);
1654                                 int vol = tltable[FM_TLPOS+(db << (FM_TLBITS-7))] >> 4;
1655                                 int maskl = -((r.pan >> 1) & 1);
1656                                 int maskr = -(r.pan & 1);
1657
1658                                 if (rhythmmask_ & (1 << i))
1659                                 {
1660                                         maskl = maskr = 0;
1661                                 }
1662                                 
1663                                 for (Sample* dest = buffer; dest<limit && r.pos < r.size; dest+=2)
1664                                 {
1665                                         int sample = (r.sample[r.pos / 1024] * vol) >> 12;
1666                                         r.pos += r.step;
1667                                         StoreSample(dest[0], sample & maskl);
1668                                         StoreSample(dest[1], sample & maskr);
1669                                 }
1670                         }
1671                 }
1672         }
1673 }
1674
1675 // ---------------------------------------------------------------------------
1676 //      \89¹\97Ê\90Ý\92è
1677 //
1678 void OPNA::SetVolumeRhythmTotal(int db)
1679 {
1680         db = Min(db, 20);
1681         rhythmtvol = -(db * 2 / 3);
1682 }
1683
1684 void OPNA::SetVolumeRhythm(int index, int db)
1685 {
1686         db = Min(db, 20);
1687         rhythm[index].volume = -(db * 2 / 3);
1688 }
1689
1690 void OPNA::SetVolumeADPCM(int db)
1691 {
1692         db = Min(db, 20);
1693         if (db > -192)
1694                 adpcmvol = int(65536.0 * pow(10.0, db / 40.0));
1695         else
1696                 adpcmvol = 0;
1697
1698         adpcmvolume = (adpcmvol * adpcmlevel) >> 12;
1699 }
1700
1701 // ---------------------------------------------------------------------------
1702 //      \8d\87\90¬
1703 //      in:             buffer          \8d\87\90¬\90æ
1704 //                      nsamples        \8d\87\90¬\83T\83\93\83v\83\8b\90\94
1705 //
1706 void OPNA::Mix(Sample* buffer, int nsamples)
1707 {
1708         FMMix(buffer, nsamples);
1709         psg.Mix(buffer, nsamples);
1710         ADPCMBMix(buffer, nsamples);
1711         RhythmMix(buffer, nsamples);
1712 }
1713
1714 // ---------------------------------------------------------------------------
1715 //      \83X\83e\81[\83g\83Z\81[\83u
1716 //
1717 #define OPNA_STATE_VERSION      1
1718
1719 void OPNA::SaveState(void *f)
1720 {
1721         FILEIO *state_fio = (FILEIO *)f;
1722         
1723         state_fio->FputUint32(OPNA_STATE_VERSION);
1724         
1725         OPNABase::SaveState(f);
1726         for(int i = 0; i < 6; i++) {
1727                 state_fio->FputUint8(rhythm[i].pan);
1728                 state_fio->FputInt8(rhythm[i].level);
1729                 state_fio->FputUint32(rhythm[i].pos);
1730         }
1731         state_fio->FputInt8(rhythmtl);
1732         state_fio->FputInt32(rhythmtvol);
1733         state_fio->FputUint8(rhythmkey);
1734 }
1735
1736 bool OPNA::LoadState(void *f)
1737 {
1738         FILEIO *state_fio = (FILEIO *)f;
1739         
1740         if(state_fio->FgetUint32() != OPNA_STATE_VERSION) {
1741                 return false;
1742         }
1743         if(!OPNABase::LoadState(f)) {
1744                 return false;
1745         }
1746         for(int i = 0; i < 6; i++) {
1747                 rhythm[i].pan = state_fio->FgetUint8();
1748                 rhythm[i].level = state_fio->FgetInt8();
1749                 rhythm[i].pos = state_fio->FgetUint32();
1750         }
1751         rhythmtl = state_fio->FgetInt8();
1752         rhythmtvol = state_fio->FgetInt32();
1753         rhythmkey = state_fio->FgetUint8();
1754         return true;
1755 }
1756
1757 #endif // BUILD_OPNA
1758
1759 // ---------------------------------------------------------------------------
1760 //      YM2610(OPNB)
1761 // ---------------------------------------------------------------------------
1762
1763 #ifdef BUILD_OPNB
1764
1765 // ---------------------------------------------------------------------------
1766 //      \8d\\92z
1767 //
1768 OPNB::OPNB()
1769 {
1770         adpcmabuf = 0;
1771         adpcmasize = 0;
1772         for (int i=0; i<6; i++)
1773         {
1774                 adpcma[i].pan = 0;
1775                 adpcma[i].level = 0;
1776                 adpcma[i].volume = 0;
1777                 adpcma[i].pos = 0;
1778                 adpcma[i].step = 0;
1779                 adpcma[i].volume = 0;
1780                 adpcma[i].start = 0;
1781                 adpcma[i].stop = 0;
1782                 adpcma[i].adpcmx = 0;
1783                 adpcma[i].adpcmd = 0;
1784         }
1785         adpcmatl = 0;
1786         adpcmakey = 0;
1787         adpcmatvol = 0;
1788         adpcmmask = 0;
1789         adpcmnotice = 0x8000;
1790         granuality = -1;
1791         csmch = &ch[2];
1792
1793         InitADPCMATable();
1794 }
1795
1796 OPNB::~OPNB()
1797 {
1798 }
1799
1800 // ---------------------------------------------------------------------------
1801 //      \8f\89\8aú\89»
1802 //
1803 bool OPNB::Init(uint c, uint r, bool ipflag,
1804                                 uint8 *_adpcma, int _adpcma_size,
1805                                 uint8 *_adpcmb, int _adpcmb_size)
1806 {
1807         int i;
1808         if (!SetRate(c, r, ipflag))
1809                 return false;
1810         if (!OPNABase::Init(c, r, ipflag))
1811                 return false;
1812         
1813         adpcmabuf = _adpcma;
1814         adpcmasize = _adpcma_size;
1815         adpcmbuf = _adpcmb;
1816
1817         for (i=0; i<=24; i++)           // max 16M bytes
1818         {
1819                 if (_adpcmb_size <= (1 << i))
1820                 {
1821                         adpcmmask = (1 << i) - 1;
1822                         break;
1823                 }
1824         }
1825
1826 //      adpcmmask = _adpcmb_size - 1;
1827         limitaddr = adpcmmask;
1828         
1829         Reset();
1830
1831         SetVolumeFM(0);
1832         SetVolumePSG(0);
1833         SetVolumeADPCMB(0);
1834         SetVolumeADPCMATotal(0);
1835         for (i=0; i<6; i++)
1836                 SetVolumeADPCMA(i, 0);
1837         SetChannelMask(0);
1838         return true;
1839 }
1840
1841 // ---------------------------------------------------------------------------
1842 //      \83\8a\83Z\83b\83g
1843 //
1844 void OPNB::Reset()
1845 {
1846         OPNABase::Reset();
1847         
1848         stmask = ~0;
1849         adpcmakey = 0;
1850         reg29 = ~0;
1851         
1852         for (int i=0; i<6; i++) 
1853         {
1854                 adpcma[i].pan = 0;
1855                 adpcma[i].level = 0;
1856                 adpcma[i].volume = 0;
1857                 adpcma[i].pos = 0;
1858                 adpcma[i].step = 0;
1859                 adpcma[i].volume = 0;
1860                 adpcma[i].start = 0;
1861                 adpcma[i].stop = 0;
1862                 adpcma[i].adpcmx = 0;
1863                 adpcma[i].adpcmd = 0;
1864         }
1865 }
1866
1867 // ---------------------------------------------------------------------------
1868 //      \83T\83\93\83v\83\8a\83\93\83O\83\8c\81[\83g\95Ï\8dX
1869 //
1870 bool OPNB::SetRate(uint c, uint r, bool ipflag)
1871 {
1872         if (!OPNABase::SetRate(c, r, ipflag))
1873                 return false;
1874
1875         adpcmastep = int(double(c) / 54 * 8192 / r);
1876         return true;
1877 }
1878
1879 // ---------------------------------------------------------------------------
1880 //      \83\8c\83W\83X\83^\83A\83\8c\83C\82É\83f\81[\83^\82ð\90Ý\92è
1881 //
1882 void OPNB::SetReg(uint addr, uint data)
1883 {
1884         addr &= 0x1ff;
1885
1886         switch (addr)
1887         {
1888         // omitted registers
1889         case 0x29:
1890         case 0x2d: case 0x2e: case 0x2f:
1891                 break;
1892         
1893         // ADPCM A ---------------------------------------------------------------
1894         case 0x100:                     // DM/KEYON
1895                 if (!(data & 0x80))  // KEY ON
1896                 {
1897                         adpcmakey |= data & 0x3f;
1898                         for (int c=0; c<6; c++) 
1899                         {
1900                                 if (data & (1<<c))
1901                                 {
1902                                         ResetStatus(0x100 << c);
1903                                         adpcma[c].pos = adpcma[c].start;
1904 //                                      adpcma[c].step = 0x10000 - adpcma[c].step;
1905                                         adpcma[c].step = 0;
1906                                         adpcma[c].adpcmx = 0;
1907                                         adpcma[c].adpcmd = 0;
1908                                         adpcma[c].nibble = 0;
1909                                 }
1910                         }
1911                 }
1912                 else
1913                 {                                       // DUMP
1914                         adpcmakey &= ~data;
1915                 }
1916                 break;
1917
1918         case 0x101:
1919                 adpcmatl = ~data & 63;
1920                 break;
1921
1922         case 0x108:     case 0x109:     case 0x10a:     
1923         case 0x10b: case 0x10c: case 0x10d:
1924                 adpcma[addr & 7].pan   = (data >> 6) & 3;
1925                 adpcma[addr & 7].level = ~data & 31;
1926                 break;
1927
1928         case 0x110: case 0x111: case 0x112:     // START ADDRESS (L)
1929         case 0x113: case 0x114: case 0x115:
1930         case 0x118: case 0x119: case 0x11a:     // START ADDRESS (H)
1931         case 0x11b: case 0x11c: case 0x11d:
1932                 adpcmareg[addr - 0x110] = data;
1933                 adpcma[addr & 7].pos = adpcma[addr & 7].start = 
1934                         (adpcmareg[(addr&7)+8]*256+adpcmareg[addr&7]) << 9;
1935                 break;
1936
1937         case 0x120: case 0x121: case 0x122:     // END ADDRESS (L)
1938         case 0x123: case 0x124: case 0x125:
1939         case 0x128: case 0x129: case 0x12a:     // END ADDRESS (H)
1940         case 0x12b: case 0x12c: case 0x12d:
1941                 adpcmareg[addr - 0x110] = data;
1942                 adpcma[addr & 7].stop = 
1943                         (adpcmareg[(addr&7)+24]*256+adpcmareg[(addr&7)+16] + 1) << 9;
1944                 break;
1945
1946         // ADPCMB -----------------------------------------------------------------
1947         case 0x10: 
1948                 if ((data & 0x80) && !adpcmplay)
1949                 {
1950                         adpcmplay = true;
1951                         memaddr = startaddr;
1952                         adpcmx = 0, adpcmd = 127;
1953                         adplc = 0;
1954                 }
1955                 if (data & 1)
1956                         adpcmplay = false;
1957                 control1 = data & 0x91;
1958                 break;
1959
1960
1961         case 0x11:              // Control Register 2
1962                 control2 = data & 0xc0;
1963                 break;
1964
1965         case 0x12:              // Start Address L
1966         case 0x13:              // Start Address H
1967                 adpcmreg[addr - 0x12 + 0] = data;
1968                 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 9;
1969                 memaddr = startaddr;
1970                 break;
1971
1972         case 0x14:              // Stop Address L
1973         case 0x15:              // Stop Address H
1974                 adpcmreg[addr - 0x14 + 2] = data;
1975                 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 9;
1976 //              LOG1("  stopaddr %.6x", stopaddr);
1977                 break;
1978
1979         case 0x19:              // delta-N L
1980         case 0x1a:              // delta-N H
1981                 adpcmreg[addr - 0x19 + 4] = data;
1982                 deltan = adpcmreg[5]*256+adpcmreg[4];
1983                 deltan = Max(256, deltan);
1984                 adpld = deltan * adplbase >> 16;
1985                 break;
1986
1987         case 0x1b:              // Level Control
1988                 adpcmlevel = data; 
1989                 adpcmvolume = (adpcmvol * adpcmlevel) >> 12;
1990                 break;
1991
1992         case 0x1c:              // Flag Control
1993                 stmask = ~((data & 0xbf) << 8);
1994                 status &= stmask;
1995                 UpdateStatus();
1996                 break;
1997
1998         default:
1999                 OPNABase::SetReg(addr, data);
2000                 break;
2001         }
2002 //      LOG0("\n");
2003 }
2004
2005 // ---------------------------------------------------------------------------
2006 //      \83\8c\83W\83X\83^\8eæ\93¾
2007 //
2008 uint OPNB::GetReg(uint addr)
2009 {
2010         if (addr < 0x10)
2011                 return psg.GetReg(addr);
2012
2013         return 0;
2014 }
2015
2016 // ---------------------------------------------------------------------------
2017 //      \8ag\92£\83X\83e\81[\83^\83X\82ð\93Ç\82Ý\82±\82Þ
2018 //
2019 uint OPNB::ReadStatusEx()
2020 {
2021         return (status & stmask) >> 8;
2022 }
2023
2024 // ---------------------------------------------------------------------------
2025 //      YM2610
2026 //
2027 int OPNB::jedi_table[(48+1)*16];
2028
2029 void OPNB::InitADPCMATable()
2030 {
2031         const static int8 table2[] = 
2032         {
2033                  1,  3,  5,  7,  9, 11, 13, 15,
2034                 -1, -3, -5, -7, -9,-11,-13,-15,
2035         };
2036
2037         for (int i=0; i<=48; i++)
2038         {
2039                 int s = int(16.0 * pow (1.1, i) * 3);
2040                 for (int j=0; j<16; j++)
2041                 {
2042                         jedi_table[i*16+j] = s * table2[j] / 8;
2043                 }
2044         }
2045 }
2046
2047 // ---------------------------------------------------------------------------
2048 //      ADPCMA \8d\87\90¬
2049 //
2050 void OPNB::ADPCMAMix(Sample* buffer, uint count)
2051 {
2052         const static int decode_tableA1[16] = 
2053         {
2054                 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
2055                 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
2056         };
2057
2058         if (adpcmatvol < 128 && (adpcmakey & 0x3f))
2059         {
2060                 Sample* limit = buffer + count * 2;
2061                 for (int i=0; i<6; i++)
2062                 {
2063                         ADPCMA& r = adpcma[i];
2064                         if ((adpcmakey & (1 << i)) && r.level < 128)
2065                         {
2066                                 uint maskl = r.pan & 2 ? -1 : 0;
2067                                 uint maskr = r.pan & 1 ? -1 : 0;
2068                                 if (rhythmmask_ & (1 << i))
2069                                 {
2070                                         maskl = maskr = 0;
2071                                 }
2072
2073                                 int db = Limit(adpcmatl+adpcmatvol+r.level+r.volume, 127, -31);
2074                                 int vol = tltable[FM_TLPOS+(db << (FM_TLBITS-7))] >> 4;
2075                                 
2076                                 Sample* dest = buffer;
2077                                 for ( ; dest<limit; dest+=2) 
2078                                 {
2079                                         r.step += adpcmastep;
2080                                         if (r.pos >= r.stop) 
2081                                         {
2082                                                 SetStatus(0x100 << i);
2083                                                 adpcmakey &= ~(1<<i);
2084                                                 break;
2085                                         }
2086                                         
2087                                         for (; r.step > 0x10000; r.step -= 0x10000)
2088                                         {
2089                                                 int data;
2090                                                 if (!(r.pos & 1)) 
2091                                                 {
2092                                                         r.nibble = adpcmabuf[r.pos>>1];
2093                                                         data = r.nibble >> 4;
2094                                                 }
2095                                                 else
2096                                                 {
2097                                                         data = r.nibble & 0x0f;
2098                                                 }
2099                                                 r.pos++;
2100
2101                                                 r.adpcmx += jedi_table[r.adpcmd + data];
2102                                                 r.adpcmx = Limit(r.adpcmx, 2048*3-1, -2048*3);
2103                                                 r.adpcmd += decode_tableA1[data];
2104                                                 r.adpcmd = Limit(r.adpcmd, 48*16, 0);
2105                                         }
2106                                         int sample = (r.adpcmx * vol) >> 10;
2107                                         StoreSample(dest[0], sample & maskl);
2108                                         StoreSample(dest[1], sample & maskr);
2109                                 }
2110                         }
2111                 }
2112         }
2113 }
2114
2115 // ---------------------------------------------------------------------------
2116 //      \89¹\97Ê\90Ý\92è
2117 //
2118 void OPNB::SetVolumeADPCMATotal(int db)
2119 {
2120         db = Min(db, 20);
2121         adpcmatvol = -(db * 2 / 3);
2122 }
2123
2124 void OPNB::SetVolumeADPCMA(int index, int db)
2125 {
2126         db = Min(db, 20);
2127         adpcma[index].volume = -(db * 2 / 3);
2128 }
2129
2130 void OPNB::SetVolumeADPCMB(int db)
2131 {
2132         db = Min(db, 20);
2133         if (db > -192)
2134                 adpcmvol = int(65536.0 * pow(10.0, db / 40.0));
2135         else
2136                 adpcmvol = 0;
2137 }
2138
2139 // ---------------------------------------------------------------------------
2140 //      \8d\87\90¬
2141 //      in:             buffer          \8d\87\90¬\90æ
2142 //                      nsamples        \8d\87\90¬\83T\83\93\83v\83\8b\90\94
2143 //
2144 void OPNB::Mix(Sample* buffer, int nsamples)
2145 {
2146         FMMix(buffer, nsamples);
2147         psg.Mix(buffer, nsamples);
2148         ADPCMBMix(buffer, nsamples);
2149         ADPCMAMix(buffer, nsamples);
2150 }
2151
2152 #endif // BUILD_OPNB
2153
2154 }       // namespace FM