OSDN Git Service

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