OSDN Git Service

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