OSDN Git Service

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