OSDN Git Service

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