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 $
12 #include "../../fileio.h"
20 // OPN ch3
\82ª
\8fí
\82ÉPrepare
\82Ì
\91Î
\8fÛ
\82Æ
\82È
\82Á
\82Ä
\82µ
\82Ü
\82¤
\8fá
\8aQ
23 // ---------------------------------------------------------------------------
24 // OPNA: ADPCM
\83f
\81[
\83^
\82Ì
\8ai
\94[
\95û
\8e®
\82Ì
\88á
\82¢ (8bit/1bit)
\82ð
\83G
\83~
\83\85\83\8c\81[
\83g
\82µ
\82È
\82¢
25 //
\82±
\82Ì
\83I
\83v
\83V
\83\87\83\93\82ð
\97L
\8cø
\82É
\82·
\82é
\82Æ ADPCM
\83\81\83\82\83\8a\82Ö
\82Ì
\83A
\83N
\83Z
\83X(
\93Á
\82É 8bit
\83\82\81[
\83h)
\82ª
26 //
\91½
\8f
\8cy
\82
\82È
\82é
\82©
\82à
28 //#define NO_BITTYPE_EMULATION
37 // ---------------------------------------------------------------------------
40 #if defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB)
42 uint32 OPNBase::lfotable[8]; // OPNA/B
\97p
50 //
\83p
\83\89\83\81\81[
\83^
\83Z
\83b
\83g
51 void OPNBase::SetParameter(Channel4* ch, uint addr, uint data)
53 const static uint slottable[4] = { 0, 2, 1, 3 };
54 const static uint8 sltable[16] =
56 0, 4, 8, 12, 16, 20, 24, 28,
57 32, 36, 40, 44, 48, 52, 56, 124,
62 uint slot = slottable[(addr >> 2) & 3];
63 Operator* op = &ch->op[slot];
65 switch ((addr >> 4) & 15)
67 case 3: // 30-3E DT/MULTI
68 op->SetDT((data >> 4) & 0x07);
69 op->SetMULTI(data & 0x0f);
73 op->SetTL(data & 0x7f, ((regtc & 0xc0) == 0x80) && (csmch == ch));
76 case 5: // 50-5E KS/AR
77 op->SetKS((data >> 6) & 3);
78 op->SetAR((data & 0x1f) * 2);
81 case 6: // 60-6E DR/AMON
82 op->SetDR((data & 0x1f) * 2);
83 op->SetAMON((data & 0x80) != 0);
87 op->SetSR((data & 0x1f) * 2);
90 case 8: // 80-8E SL/RR
91 op->SetSL(sltable[(data >> 4) & 15]);
92 op->SetRR((data & 0x0f) * 4 + 2);
95 case 9: // 90-9E SSG-EC
96 op->SetSSGEC(data & 0x0f);
102 //
\83\8a\83Z
\83b
\83g
103 void OPNBase::Reset()
112 //
\8a\84\82è
\8d\9e\82Ý
\90M
\8d\86\82Ì
\8eæ
\93¾
113 bool OPNBase::ReadIRQ()
118 //
\83v
\83\8a\83X
\83P
\81[
\83\89\90Ý
\92è
119 void OPNBase::SetPrescaler(uint p)
121 static const char table[3][2] = { { 6, 4 }, { 3, 2 }, { 2, 1 } };
122 static const uint8 table2[8] = { 108, 77, 71, 67, 62, 44, 8, 5 };
127 assert(0 <= prescale && prescale < 3);
129 uint fmclock = clock / table[p][0] / 12;
133 //
\8d\87\90¬
\8eü
\94g
\90\94\82Æ
\8fo
\97Í
\8eü
\94g
\90\94\82Ì
\94ä
134 assert(fmclock < (0x80000000 >> FM_RATIOBITS));
135 uint ratio = ((fmclock << FM_RATIOBITS) + rate/2) / rate;
137 SetTimerPrescaler(table[p][0] * 12);
138 // MakeTimeTable(ratio);
139 chip.SetRatio(ratio);
140 psg.SetClock(clock / table[p][1], psgrate);
142 for (int i=0; i<8; i++)
144 lfotable[i] = (ratio << (2+FM_LFOCBITS-FM_RATIOBITS)) / table2[i];
150 bool OPNBase::Init(uint c, uint r)
159 void OPNBase::SetVolumeFM(int db_l, int db_r)
161 db_l = Min(db_l, 20);
162 db_r = Min(db_r, 20);
165 fmvolume_l = int(16384.0 * pow(10.0, db_l / 40.0));
169 fmvolume_r = int(16384.0 * pow(10.0, db_r / 40.0));
174 //
\83^
\83C
\83}
\81[
\8e\9e\8aÔ
\8f\88\97\9d
175 void OPNBase::TimerA()
177 if ((regtc & 0xc0) == 0x80)
179 csmch->KeyControl(0x00);
180 csmch->KeyControl(0x0f);
184 //
\8a\84\82è
\8d\9e\82Ý
\90M
\8d\86\82Ì
\90Ý
\92è
185 void OPNBase::Intr(bool value)
190 // ---------------------------------------------------------------------------
191 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
193 #define OPN_BASE_STATE_VERSION 4
195 void OPNBase::SaveState(void *f)
197 FILEIO *state_fio = (FILEIO *)f;
199 state_fio->FputUint32_BE(OPN_BASE_STATE_VERSION);
202 state_fio->FputInt32_BE(fmvolume_l);
203 state_fio->FputInt32_BE(fmvolume_r);
204 state_fio->FputUint32_BE(clock);
205 state_fio->FputUint32_BE(rate);
206 state_fio->FputUint32_BE(psgrate);
207 state_fio->FputUint32_BE(status);
208 state_fio->FputBool(interrupt);
209 state_fio->FputUint8(prescale);
214 bool OPNBase::LoadState(void *f)
216 FILEIO *state_fio = (FILEIO *)f;
218 if(state_fio->FgetUint32_BE() != OPN_BASE_STATE_VERSION) {
221 if(!Timer::LoadState(f)) {
224 fmvolume_l = state_fio->FgetInt32_BE();
225 fmvolume_r = state_fio->FgetInt32_BE();
226 clock = state_fio->FgetUint32_BE();
227 rate = state_fio->FgetUint32_BE();
228 psgrate = state_fio->FgetUint32_BE();
229 status = state_fio->FgetUint32_BE();
230 interrupt = state_fio->FgetBool();
231 prescale = state_fio->FgetUint8();
232 if(!chip.LoadState(f)) {
235 if(!psg.LoadState(f)) {
241 #endif // defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB)
243 // ---------------------------------------------------------------------------
255 for (int i=0; i<3; i++)
257 ch[i].SetChip(&chip);
258 ch[i].SetType(typeN);
263 bool OPN::Init(uint c, uint r, bool ip, const char*)
265 if (!SetRate(c, r, ip))
276 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
277 bool OPN::SetRate(uint c, uint r, bool)
285 //
\83\8a\83Z
\83b
\83g
289 for (i=0x20; i<0x28; i++) SetReg(i, 0);
290 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
298 //
\83\8c\83W
\83X
\83^
\93Ç
\82Ý
\8d\9e\82Ý
299 uint OPN::GetReg(uint addr)
302 return psg.GetReg(addr);
308 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
309 void OPN::SetReg(uint addr, uint data)
311 // LOG2("reg[%.2x] <- %.2x\n", addr, data);
318 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
319 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
320 psg.SetReg(addr, data);
323 case 0x24: case 0x25:
324 SetTimerA(addr, data);
332 SetTimerControl(data);
335 case 0x28: // Key On/Off
337 ch[data & 3].KeyControl(data >> 4);
340 case 0x2d: case 0x2e: case 0x2f:
341 SetPrescaler(addr-0x2d);
345 case 0xa0: case 0xa1: case 0xa2:
346 fnum[c] = data + fnum2[c] * 0x100;
349 case 0xa4: case 0xa5: case 0xa6:
350 fnum2[c] = uint8(data);
353 case 0xa8: case 0xa9: case 0xaa:
354 fnum3[c] = data + fnum2[c+3] * 0x100;
357 case 0xac: case 0xad: case 0xae:
358 fnum2[c+3] = uint8(data);
361 case 0xb0: case 0xb1: case 0xb2:
362 ch[c].SetFB((data >> 3) & 7);
363 ch[c].SetAlgorithm(data & 7);
369 if ((addr & 0xf0) == 0x60)
371 OPNBase::SetParameter(&ch[c], addr, data);
377 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
378 void OPN::SetStatus(uint bits)
380 if (!(status & bits))
387 void OPN::ResetStatus(uint bit)
394 //
\83}
\83X
\83N
\90Ý
\92è
395 void OPN::SetChannelMask(uint mask)
397 for (int i=0; i<3; i++)
398 ch[i].Mute(!!(mask & (1 << i)));
399 psg.SetChannelMask(mask >> 6);
404 void OPN::Mix(Sample* buffer, int nsamples)
406 #define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
407 #define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
409 psg.Mix(buffer, nsamples);
412 ch[0].SetFNum(fnum[0]);
413 ch[1].SetFNum(fnum[1]);
415 ch[2].SetFNum(fnum[2]);
418 ch[2].op[0].SetFNum(fnum3[1]);
419 ch[2].op[1].SetFNum(fnum3[2]);
420 ch[2].op[2].SetFNum(fnum3[0]);
421 ch[2].op[3].SetFNum(fnum[2]);
424 int actch = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
427 Sample* limit = buffer + nsamples * 2;
428 for (Sample* dest = buffer; dest < limit; dest+=2)
432 if (actch & 0x01) s = ch[0].Calc();
433 if (actch & 0x04) s += ch[1].Calc();
434 if (actch & 0x10) s += ch[2].Calc();
435 s_l = IStoSampleL(s);
436 s_r = IStoSampleR(s);
437 StoreSample(dest[0], s_l);
438 StoreSample(dest[1], s_r);
445 // ---------------------------------------------------------------------------
446 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
448 #define OPN_STATE_VERSION 2
450 void OPN::SaveState(void *f)
452 FILEIO *state_fio = (FILEIO *)f;
454 state_fio->FputUint32_BE(OPN_STATE_VERSION);
456 OPNBase::SaveState(f);
457 for(int i = 0; i < 3; i++) {
458 state_fio->FputUint32_BE(fnum[i]);
460 for(int i = 0; i < 3; i++) {
461 state_fio->FputUint32_BE(fnum3[i]);
463 //state_fio->Fwrite(fnum, sizeof(fnum), 1);
464 //state_fio->Fwrite(fnum3, sizeof(fnum3), 1);
465 state_fio->Fwrite(fnum2, sizeof(fnum2), 1);
466 for(int i = 0; i < 3; i++) {
471 bool OPN::LoadState(void *f)
473 FILEIO *state_fio = (FILEIO *)f;
475 if(state_fio->FgetUint32_BE() != OPN_STATE_VERSION) {
478 if(!OPNBase::LoadState(f)) {
481 for(int i = 0; i < 3; i++) {
482 fnum[i] = state_fio->FgetUint32_BE();
484 for(int i = 0; i < 3; i++) {
485 fnum3[i] = state_fio->FgetUint32_BE();
487 //state_fio->Fread(fnum, sizeof(fnum), 1);
488 //state_fio->Fread(fnum3, sizeof(fnum3), 1);
489 state_fio->Fread(fnum2, sizeof(fnum2), 1);
490 for(int i = 0; i < 3; i++) {
491 if(!ch[i].LoadState(f)) {
500 // ---------------------------------------------------------------------------
501 // YM2608/2610 common part
502 // ---------------------------------------------------------------------------
504 #if defined(BUILD_OPNA) || defined(BUILD_OPNB)
506 int OPNABase::amtable[FM_LFOENTS] = { -1, };
507 int OPNABase::pmtable[FM_LFOENTS];
509 int32 OPNABase::tltable[FM_TLENTS+FM_TLPOS];
510 bool OPNABase::tablehasmade = false;
525 for (int i=0; i<6; i++)
527 ch[i].SetChip(&chip);
528 ch[i].SetType(typeN);
532 OPNABase::~OPNABase()
536 // ---------------------------------------------------------------------------
539 bool OPNABase::Init(uint c, uint r, bool)
551 // ---------------------------------------------------------------------------
552 //
\83e
\81[
\83u
\83\8b\8dì
\90¬
554 void OPNABase::MakeTable2()
558 for (int i=-FM_TLPOS; i<FM_TLENTS; i++)
560 tltable[i+FM_TLPOS] = uint(65536. * pow(2.0, i * -16. / FM_TLENTS))-1;
567 // ---------------------------------------------------------------------------
568 //
\83\8a\83Z
\83b
\83g
570 void OPNABase::Reset()
575 for (i=0x20; i<0x28; i++) SetReg(i, 0);
576 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
577 for (i=0x130; i<0x1c0; i++) SetReg(i, 0);
578 for (i=0x100; i<0x110; i++) SetReg(i, 0);
579 for (i=0x10; i<0x20; i++) SetReg(i, 0);
593 apout0_l = apout1_l = adpcmout_l = 0;
594 apout0_r = apout1_r = adpcmout_r = 0;
603 // ---------------------------------------------------------------------------
604 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
606 bool OPNABase::SetRate(uint c, uint r, bool)
608 c /= 2; //
\8f]
\97\88\94Å
\82Æ
\82Ì
\8cÝ
\8a·
\90«
\82ð
\8fd
\8e\8b\82µ
\82½
\82¯
\82è
\82á
\83R
\83\81\83\93\83g
\83A
\83E
\83g
\82µ
\82æ
\82¤
612 adplbase = int(8192. * (clock/72.) / r);
613 adpld = deltan * adplbase >> 16;
617 lfodcount = reg22 & 0x08 ? lfotable[reg22 & 7] : 0;
622 // ---------------------------------------------------------------------------
623 //
\83`
\83\83\83\93\83l
\83\8b\83}
\83X
\83N
\82Ì
\90Ý
\92è
625 void OPNABase::SetChannelMask(uint mask)
627 for (int i=0; i<6; i++)
628 ch[i].Mute(!!(mask & (1 << i)));
629 psg.SetChannelMask(mask >> 6);
630 adpcmmask_ = (mask & (1 << 9)) != 0;
631 rhythmmask_ = (mask >> 10) & ((1 << 6) - 1);
634 // ---------------------------------------------------------------------------
635 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
637 void OPNABase::SetReg(uint addr, uint data)
644 // Timer -----------------------------------------------------------------
645 case 0x24: case 0x25:
646 SetTimerA(addr, data);
654 SetTimerControl(data);
657 // Misc ------------------------------------------------------------------
658 case 0x28: // Key On/Off
661 c = (data & 3) + (data & 4 ? 3 : 0);
662 ch[c].KeyControl(data >> 4);
666 // Status Mask -----------------------------------------------------------
669 // UpdateStatus(); //?
672 // Prescaler -------------------------------------------------------------
673 case 0x2d: case 0x2e: case 0x2f:
674 SetPrescaler(addr-0x2d);
677 // F-Number --------------------------------------------------------------
678 case 0x1a0: case 0x1a1: case 0x1a2:
680 case 0xa0: case 0xa1: case 0xa2:
681 fnum[c] = data + fnum2[c] * 0x100;
682 ch[c].SetFNum(fnum[c]);
685 case 0x1a4: case 0x1a5: case 0x1a6:
687 case 0xa4 : case 0xa5: case 0xa6:
688 fnum2[c] = uint8(data);
691 case 0xa8: case 0xa9: case 0xaa:
692 fnum3[c] = data + fnum2[c+6] * 0x100;
695 case 0xac : case 0xad: case 0xae:
696 fnum2[c+6] = uint8(data);
699 // Algorithm -------------------------------------------------------------
701 case 0x1b0: case 0x1b1: case 0x1b2:
703 case 0xb0: case 0xb1: case 0xb2:
704 ch[c].SetFB((data >> 3) & 7);
705 ch[c].SetAlgorithm(data & 7);
708 case 0x1b4: case 0x1b5: case 0x1b6:
710 case 0xb4: case 0xb5: case 0xb6:
711 pan[c] = (data >> 6) & 3;
715 // LFO -------------------------------------------------------------------
717 modified = reg22 ^ data;
721 lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0;
724 // PSG -------------------------------------------------------------------
725 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
726 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
727 psg.SetReg(addr, data);
730 //
\89¹
\90F ------------------------------------------------------------------
736 OPNBase::SetParameter(&ch[c], addr, data);
742 // ---------------------------------------------------------------------------
745 void OPNABase::SetADPCMBReg(uint addr, uint data)
749 case 0x00: // Control Register 1
750 if ((data & 0x80) && !adpcmplay)
754 adpcmx = 0, adpcmd = 127;
764 case 0x01: // Control Register 2
766 granuality = control2 & 2 ? 1 : 4;
769 case 0x02: // Start Address L
770 case 0x03: // Start Address H
771 adpcmreg[addr - 0x02 + 0] = data;
772 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 6;
774 // LOG1(" startaddr %.6x", startaddr);
777 case 0x04: // Stop Address L
778 case 0x05: // Stop Address H
779 adpcmreg[addr - 0x04 + 2] = data;
780 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 6;
781 // LOG1(" stopaddr %.6x", stopaddr);
784 case 0x08: // ADPCM data
785 if ((control1 & 0x60) == 0x60)
787 // LOG2(" Wr [0x%.5x] = %.2x", memaddr, data);
792 case 0x09: // delta-N L
793 case 0x0a: // delta-N H
794 adpcmreg[addr - 0x09 + 4] = data;
795 deltan = adpcmreg[5]*256+adpcmreg[4];
796 deltan = Max(256, deltan);
797 adpld = deltan * adplbase >> 16;
800 case 0x0b: // Level Control
802 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
803 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
806 case 0x0c: // Limit Address L
807 case 0x0d: // Limit Address H
808 adpcmreg[addr - 0x0c + 6] = data;
809 limitaddr = (adpcmreg[7]*256+adpcmreg[6] + 1) << 6;
810 // LOG1(" limitaddr %.6x", limitaddr);
813 case 0x10: // Flag Control
816 // for Firecracker Music collection (Hi-speed PCM loader)
822 stmask = ~(data & 0x1f);
823 // UpdateStatus(); //???
830 // ---------------------------------------------------------------------------
831 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
833 uint OPNA::GetReg(uint addr)
836 return psg.GetReg(addr);
840 // LOG1("%d:reg[108] -> ", Diag::GetCPUTick());
842 uint data = adpcmreadbuf & 0xff;
844 if ((control1 & 0x60) == 0x20)
846 adpcmreadbuf |= ReadRAM() << 8;
847 // LOG2("Rd [0x%.6x:%.2x] ", memaddr, adpcmreadbuf >> 8);
862 // ---------------------------------------------------------------------------
863 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
865 void OPNABase::SetStatus(uint bits)
867 if (!(status & bits))
869 // LOG2("SetStatus(%.2x %.2x)\n", bits, stmask);
870 status |= bits & stmask;
874 // LOG1("SetStatus(%.2x) - ignored\n", bits);
877 void OPNABase::ResetStatus(uint bits)
880 // LOG1("ResetStatus(%.2x)\n", bits);
884 inline void OPNABase::UpdateStatus()
886 // LOG2("%d:INT = %d\n", Diag::GetCPUTick(), (status & stmask & reg29) != 0);
887 Intr((status & stmask & reg29) != 0);
890 // ---------------------------------------------------------------------------
891 // ADPCM RAM
\82Ö
\82Ì
\8f\91\8d\9e\82Ý
\91\80\8dì
893 void OPNABase::WriteRAM(uint data)
895 #ifndef NO_BITTYPE_EMULATION
899 adpcmbuf[(memaddr >> 4) & 0x3ffff] = data;
905 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
906 uint bank = (memaddr >> 1) & 7;
907 uint8 mask = 1 << bank;
910 p[0x00000] = (p[0x00000] & ~mask) | (uint8(data) & mask); data >>= 1;
911 p[0x08000] = (p[0x08000] & ~mask) | (uint8(data) & mask); data >>= 1;
912 p[0x10000] = (p[0x10000] & ~mask) | (uint8(data) & mask); data >>= 1;
913 p[0x18000] = (p[0x18000] & ~mask) | (uint8(data) & mask); data >>= 1;
914 p[0x20000] = (p[0x20000] & ~mask) | (uint8(data) & mask); data >>= 1;
915 p[0x28000] = (p[0x28000] & ~mask) | (uint8(data) & mask); data >>= 1;
916 p[0x30000] = (p[0x30000] & ~mask) | (uint8(data) & mask); data >>= 1;
917 p[0x38000] = (p[0x38000] & ~mask) | (uint8(data) & mask);
921 adpcmbuf[(memaddr >> granuality) & 0x3ffff] = data;
922 memaddr += 1 << granuality;
925 if (memaddr == stopaddr)
928 statusnext = 0x04; // EOS
931 if (memaddr == limitaddr)
933 // LOG1("Limit ! (%.8x)\n", limitaddr);
939 // ---------------------------------------------------------------------------
940 // ADPCM RAM
\82©
\82ç
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
\91\80\8dì
942 uint OPNABase::ReadRAM()
945 #ifndef NO_BITTYPE_EMULATION
949 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
955 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
956 uint bank = (memaddr >> 1) & 7;
957 uint8 mask = 1 << bank;
959 data = (p[0x38000] & mask);
960 data = data * 2 + (p[0x30000] & mask);
961 data = data * 2 + (p[0x28000] & mask);
962 data = data * 2 + (p[0x20000] & mask);
963 data = data * 2 + (p[0x18000] & mask);
964 data = data * 2 + (p[0x10000] & mask);
965 data = data * 2 + (p[0x08000] & mask);
966 data = data * 2 + (p[0x00000] & mask);
971 data = adpcmbuf[(memaddr >> granuality) & 0x3ffff];
972 memaddr += 1 << granuality;
974 if (memaddr == stopaddr)
977 statusnext = 0x04; // EOS
980 if (memaddr == limitaddr)
982 // LOG1("Limit ! (%.8x)\n", limitaddr);
985 if (memaddr < stopaddr)
991 inline int OPNABase::DecodeADPCMBSample(uint data)
993 static const int table1[16] =
995 1, 3, 5, 7, 9, 11, 13, 15,
996 -1, -3, -5, -7, -9, -11, -13, -15,
998 static const int table2[16] =
1000 57, 57, 57, 57, 77, 102, 128, 153,
1001 57, 57, 57, 57, 77, 102, 128, 153,
1003 adpcmx = Limit(adpcmx + table1[data] * adpcmd / 8, 32767, -32768);
1004 adpcmd = Limit(adpcmd * table2[data] / 64, 24576, 127);
1009 // ---------------------------------------------------------------------------
1010 // ADPCM RAM
\82©
\82ç
\82Ì nibble
\93Ç
\82Ý
\8d\9e\82Ý
\8by
\82Ñ ADPCM
\93W
\8aJ
1012 int OPNABase::ReadRAMN()
1017 #ifndef NO_BITTYPE_EMULATION
1018 if (!(control2 & 2))
1020 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
1023 return DecodeADPCMBSample(data >> 4);
1028 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff] + ((~memaddr & 1) << 17);
1029 uint bank = (memaddr >> 1) & 7;
1030 uint8 mask = 1 << bank;
1032 data = (p[0x18000] & mask);
1033 data = data * 2 + (p[0x10000] & mask);
1034 data = data * 2 + (p[0x08000] & mask);
1035 data = data * 2 + (p[0x00000] & mask);
1039 return DecodeADPCMBSample(data);
1042 data = adpcmbuf[(memaddr >> granuality) & adpcmmask];
1043 memaddr += 1 << (granuality-1);
1044 if (memaddr & (1 << (granuality-1)))
1045 return DecodeADPCMBSample(data >> 4);
1051 data = adpcmbuf[(memaddr >> 1) & adpcmmask];
1054 return DecodeADPCMBSample(data >> 4);
1058 DecodeADPCMBSample(data);
1061 if (memaddr == stopaddr)
1063 if (control1 & 0x10)
1065 memaddr = startaddr;
1067 adpcmx = 0, adpcmd = 127;
1068 // for PC-8801FA/MA shop demonstration
1069 SetStatus(adpcmnotice);
1074 memaddr &= adpcmmask; //0x3fffff;
1075 SetStatus(adpcmnotice);
1080 if (memaddr == limitaddr)
1086 // ---------------------------------------------------------------------------
1087 //
\8ag
\92£
\83X
\83e
\81[
\83^
\83X
\82ð
\93Ç
\82Ý
\82±
\82Þ
1089 uint OPNABase::ReadStatusEx()
1091 uint r = ((status | 8) & stmask) | (adpcmplay ? 0x20 : 0);
1092 status |= statusnext;
1097 // ---------------------------------------------------------------------------
1100 inline void OPNABase::DecodeADPCMB()
1102 apout0_l = apout1_l;
1103 apout0_r = apout1_r;
1104 int ram = ReadRAMN();
1105 int s_l = (ram * adpcmvolume_l) >> 13;
1106 int s_r = (ram * adpcmvolume_r) >> 13;
1107 apout1_l = adpcmout_l + s_l;
1108 apout1_r = adpcmout_r + s_r;
1113 // ---------------------------------------------------------------------------
1116 void OPNABase::ADPCMBMix(Sample* dest, uint count)
1118 uint mask_l = control2 & 0x80 ? -1 : 0;
1119 uint mask_r = control2 & 0x40 ? -1 : 0;
1122 mask_l = mask_r = 0;
1127 // LOG2("ADPCM Play: %d DeltaN: %d\n", adpld, deltan);
1128 if (adpld <= 8192) // fplay < fsamp
1130 for (; count>0; count--)
1139 int s_l = (adplc * apout0_l + (8192-adplc) * apout1_l) >> 13;
1140 int s_r = (adplc * apout0_r + (8192-adplc) * apout1_r) >> 13;
1141 StoreSample(dest[0], s_l & mask_l);
1142 StoreSample(dest[1], s_r & mask_r);
1146 for (; count>0 && (apout0_l || apout0_r); count--)
1150 apout0_l = apout1_l, apout1_l = 0;
1151 apout0_r = apout1_r, apout1_r = 0;
1154 int s_l = (adplc * apout1_l) >> 13;
1155 int s_r = (adplc * apout1_r) >> 13;
1156 StoreSample(dest[0], s_l & mask_l);
1157 StoreSample(dest[1], s_r & mask_r);
1162 else // fplay > fsamp (adpld = fplay/famp*8192)
1164 int t = (-8192*8192)/adpld;
1165 for (; count>0; count--)
1167 int s_l = apout0_l * (8192+adplc);
1168 int s_r = apout0_r * (8192+adplc);
1174 s_l -= apout0_l * Max(adplc, t);
1175 s_r -= apout0_r * Max(adplc, t);
1181 StoreSample(dest[0], s_l & mask_l);
1182 StoreSample(dest[1], s_r & mask_r);
1191 apout0_l = apout1_l = adpcmout_l = 0;
1192 apout0_r = apout1_r = adpcmout_r = 0;
1197 // ---------------------------------------------------------------------------
1199 // in: buffer
\8d\87\90¬
\90æ
1200 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
1202 void OPNABase::FMMix(Sample* buffer, int nsamples)
1204 if (fmvolume_l > 0 || fmvolume_r > 0)
1208 if (!(regtc & 0xc0))
1209 csmch->SetFNum(fnum[csmch-ch]);
1212 //
\8cø
\89Ê
\89¹
\83\82\81[
\83h
1213 csmch->op[0].SetFNum(fnum3[1]); csmch->op[1].SetFNum(fnum3[2]);
1214 csmch->op[2].SetFNum(fnum3[0]); csmch->op[3].SetFNum(fnum[2]);
1217 int act = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
1219 act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6;
1220 if (!(reg22 & 0x08))
1225 Mix6(buffer, nsamples, act);
1230 // ---------------------------------------------------------------------------
1232 void OPNABase::MixSubSL(int activech, ISample** dest)
1234 if (activech & 0x001) (*dest[0] = ch[0].CalcL());
1235 if (activech & 0x004) (*dest[1] += ch[1].CalcL());
1236 if (activech & 0x010) (*dest[2] += ch[2].CalcL());
1237 if (activech & 0x040) (*dest[3] += ch[3].CalcL());
1238 if (activech & 0x100) (*dest[4] += ch[4].CalcL());
1239 if (activech & 0x400) (*dest[5] += ch[5].CalcL());
1242 inline void OPNABase::MixSubS(int activech, ISample** dest)
1244 if (activech & 0x001) (*dest[0] = ch[0].Calc());
1245 if (activech & 0x004) (*dest[1] += ch[1].Calc());
1246 if (activech & 0x010) (*dest[2] += ch[2].Calc());
1247 if (activech & 0x040) (*dest[3] += ch[3].Calc());
1248 if (activech & 0x100) (*dest[4] += ch[4].Calc());
1249 if (activech & 0x400) (*dest[5] += ch[5].Calc());
1252 // ---------------------------------------------------------------------------
1254 void OPNABase::BuildLFOTable()
1256 if (amtable[0] == -1)
1258 for (int c=0; c<256; c++)
1261 if (c < 0x40) v = c * 2 + 0x80;
1262 else if (c < 0xc0) v = 0x7f - (c - 0x40) * 2 + 0x80;
1263 else v = (c - 0xc0) * 2;
1266 if (c < 0x80) v = 0xff - c * 2;
1267 else v = (c - 0x80) * 2;
1268 amtable[c] = v & ~3;
1273 // ---------------------------------------------------------------------------
1275 inline void OPNABase::LFO()
1277 // LOG3("%4d - %8d, %8d\n", c, lfocount, lfodcount);
1279 // Operator::SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1280 // Operator::SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1281 chip.SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1282 chip.SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1283 lfocount += lfodcount;
1286 // ---------------------------------------------------------------------------
1289 #define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
1290 #define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
1292 void OPNABase::Mix6(Sample* buffer, int nsamples, int activech)
1297 idest[0] = &ibuf[pan[0]];
1298 idest[1] = &ibuf[pan[1]];
1299 idest[2] = &ibuf[pan[2]];
1300 idest[3] = &ibuf[pan[3]];
1301 idest[4] = &ibuf[pan[4]];
1302 idest[5] = &ibuf[pan[5]];
1304 Sample* limit = buffer + nsamples * 2;
1305 for (Sample* dest = buffer; dest < limit; dest+=2)
1307 ibuf[1] = ibuf[2] = ibuf[3] = 0;
1308 if (activech & 0xaaa)
1309 LFO(), MixSubSL(activech, idest);
1311 MixSubS(activech, idest);
1312 StoreSample(dest[0], IStoSampleL(ibuf[2] + ibuf[3]));
1313 StoreSample(dest[1], IStoSampleR(ibuf[1] + ibuf[3]));
1317 // ---------------------------------------------------------------------------
1318 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
1320 #define OPNA_BASE_STATE_VERSION 2
1322 void OPNABase::SaveState(void *f)
1324 FILEIO *state_fio = (FILEIO *)f;
1326 state_fio->FputUint32_BE(OPNA_BASE_STATE_VERSION);
1328 OPNBase::SaveState(f);
1329 state_fio->Fwrite(pan, sizeof(pan), 1);
1330 state_fio->Fwrite(fnum2, sizeof(fnum2), 1);
1331 state_fio->FputUint8(reg22);
1332 state_fio->FputUint32_BE(reg29);
1333 state_fio->FputUint32_BE(stmask);
1334 state_fio->FputUint32_BE(statusnext);
1335 state_fio->FputUint32_BE(lfocount);
1336 state_fio->FputUint32_BE(lfodcount);
1337 //state_fio->Fwrite(fnum, sizeof(fnum), 1);
1338 //state_fio->Fwrite(fnum3, sizeof(fnum3), 1);
1339 for(int i = 0; i < 6; i++) {
1340 state_fio->FputUint32_BE(fnum[i]);
1342 for(int i = 0; i < 3; i++) {
1343 state_fio->FputUint32_BE(fnum3[i]);
1345 state_fio->Fwrite(adpcmbuf, 0x40000, 1);
1346 state_fio->FputUint32_BE(adpcmmask);
1347 state_fio->FputUint32_BE(adpcmnotice);
1348 state_fio->FputUint32_BE(startaddr);
1349 state_fio->FputUint32_BE(stopaddr);
1350 state_fio->FputUint32_BE(memaddr);
1351 state_fio->FputUint32_BE(limitaddr);
1352 state_fio->FputInt32_BE(adpcmlevel);
1353 state_fio->FputInt32_BE(adpcmvolume_l);
1354 state_fio->FputInt32_BE(adpcmvolume_r);
1355 state_fio->FputInt32_BE(adpcmvol_l);
1356 state_fio->FputInt32_BE(adpcmvol_r);
1357 state_fio->FputUint32_BE(deltan);
1358 state_fio->FputInt32_BE(adplc);
1359 state_fio->FputInt32_BE(adpld);
1360 state_fio->FputUint32_BE(adplbase);
1361 state_fio->FputInt32_BE(adpcmx);
1362 state_fio->FputInt32_BE(adpcmd);
1363 state_fio->FputInt32_BE(adpcmout_l);
1364 state_fio->FputInt32_BE(adpcmout_r);
1365 state_fio->FputInt32_BE(apout0_l);
1366 state_fio->FputInt32_BE(apout0_r);
1367 state_fio->FputInt32_BE(apout1_l);
1368 state_fio->FputInt32_BE(apout1_r);
1369 state_fio->FputUint32_BE(adpcmreadbuf);
1370 state_fio->FputBool(adpcmplay);
1371 state_fio->FputInt8(granuality);
1372 state_fio->FputBool(adpcmmask_);
1373 state_fio->FputUint8(control1);
1374 state_fio->FputUint8(control2);
1375 state_fio->Fwrite(adpcmreg, sizeof(adpcmreg), 1);
1376 state_fio->FputInt32_BE(rhythmmask_);
1377 for(int i = 0; i < 6; i++) {
1382 bool OPNABase::LoadState(void *f)
1384 FILEIO *state_fio = (FILEIO *)f;
1386 if(state_fio->FgetUint32_BE() != OPNA_BASE_STATE_VERSION) {
1389 if(!OPNBase::LoadState(f)) {
1392 state_fio->Fread(pan, sizeof(pan), 1);
1393 state_fio->Fread(fnum2, sizeof(fnum2), 1);
1394 reg22 = state_fio->FgetUint8();
1395 reg29 = state_fio->FgetUint32_BE();
1396 stmask = state_fio->FgetUint32_BE();
1397 statusnext = state_fio->FgetUint32_BE();
1398 lfocount = state_fio->FgetUint32_BE();
1399 lfodcount = state_fio->FgetUint32_BE();
1400 //state_fio->Fread(fnum, sizeof(fnum), 1);
1401 //state_fio->Fread(fnum3, sizeof(fnum3), 1);
1402 for(int i = 0; i < 6; i++) {
1403 fnum[i] = state_fio->FgetUint32_BE();
1405 for(int i = 0; i < 3; i++) {
1406 fnum3[i] = state_fio->FgetUint32_BE();
1408 state_fio->Fread(adpcmbuf, 0x40000, 1);
1409 adpcmmask = state_fio->FgetUint32_BE();
1410 adpcmnotice = state_fio->FgetUint32_BE();
1411 startaddr = state_fio->FgetUint32_BE();
1412 stopaddr = state_fio->FgetUint32_BE();
1413 memaddr = state_fio->FgetUint32_BE();
1414 limitaddr = state_fio->FgetUint32_BE();
1415 adpcmlevel = state_fio->FgetInt32_BE();
1416 adpcmvolume_l = state_fio->FgetInt32_BE();
1417 adpcmvolume_r = state_fio->FgetInt32_BE();
1418 adpcmvol_l = state_fio->FgetInt32_BE();
1419 adpcmvol_r = state_fio->FgetInt32_BE();
1420 deltan = state_fio->FgetUint32_BE();
1421 adplc = state_fio->FgetInt32_BE();
1422 adpld = state_fio->FgetInt32_BE();
1423 adplbase = state_fio->FgetUint32_BE();
1424 adpcmx = state_fio->FgetInt32_BE();
1425 adpcmd = state_fio->FgetInt32_BE();
1426 adpcmout_l = state_fio->FgetInt32_BE();
1427 adpcmout_r = state_fio->FgetInt32_BE();
1428 apout0_l = state_fio->FgetInt32_BE();
1429 apout0_r = state_fio->FgetInt32_BE();
1430 apout1_l = state_fio->FgetInt32_BE();
1431 apout1_r = state_fio->FgetInt32_BE();
1432 adpcmreadbuf = state_fio->FgetUint32_BE();
1433 adpcmplay = state_fio->FgetBool();
1434 granuality = state_fio->FgetInt8();
1435 adpcmmask_ = state_fio->FgetBool();
1436 control1 = state_fio->FgetUint8();
1437 control2 = state_fio->FgetUint8();
1438 state_fio->Fread(adpcmreg, sizeof(adpcmreg), 1);
1439 rhythmmask_ = state_fio->FgetInt32_BE();
1440 for(int i = 0; i < 6; i++) {
1441 if(!ch[i].LoadState(f)) {
1448 #endif // defined(BUILD_OPNA) || defined(BUILD_OPNB)
1450 // ---------------------------------------------------------------------------
1452 // ---------------------------------------------------------------------------
1456 // ---------------------------------------------------------------------------
1461 for (int i=0; i<6; i++)
1463 rhythm[i].sample = 0;
1466 rhythm[i].volume_l = 0;
1467 rhythm[i].volume_r = 0;
1468 rhythm[i].level = 0;
1473 adpcmmask = 0x3ffff;
1478 // ---------------------------------------------------------------------------
1483 for (int i=0; i<6; i++)
1484 delete[] rhythm[i].sample;
1489 // ---------------------------------------------------------------------------
1492 bool OPNA::Init(uint c, uint r, bool ipflag, const _TCHAR* path)
1495 LoadRhythmSample(path);
1498 adpcmbuf = new uint8[0x40000];
1502 if (!SetRate(c, r, ipflag))
1504 if (!OPNABase::Init(c, r, ipflag))
1509 SetVolumeADPCM(0, 0);
1510 SetVolumeRhythmTotal(0, 0);
1511 for (int i=0; i<6; i++)
1512 SetVolumeRhythm(i, 0, 0);
1516 // ---------------------------------------------------------------------------
1517 //
\83\8a\83Z
\83b
\83g
1524 limitaddr = 0x3ffff;
1528 // ---------------------------------------------------------------------------
1529 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
1531 bool OPNA::SetRate(uint c, uint r, bool ipflag)
1533 if (!OPNABase::SetRate(c, r, ipflag))
1536 for (int i=0; i<6; i++)
1538 rhythm[i].step = rhythm[i].rate * 1024 / r;
1544 // ---------------------------------------------------------------------------
1545 //
\83\8a\83Y
\83\80\89¹
\82ð
\93Ç
\82Ý
\82±
\82Þ
1547 bool OPNA::LoadRhythmSample(const _TCHAR* path)
1549 static const _TCHAR* rhythmname[6] =
1551 _T("BD"), _T("SD"), _T("TOP"), _T("HH"), _T("TOM"), _T("RIM"),
1562 _TCHAR buf[_MAX_PATH] = _T("");
1564 _tcsncpy(buf, path, _MAX_PATH);
1565 _tcsncat(buf, _T("2608_"), _MAX_PATH);
1566 _tcsncat(buf, rhythmname[i], _MAX_PATH);
1567 _tcsncat(buf, _T(".WAV"), _MAX_PATH);
1569 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1574 _tcsncpy(buf, path, _MAX_PATH);
1575 _tcsncpy(buf, _T("2608_RYM.WAV"), _MAX_PATH);
1576 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1592 file.Fseek(0x10, FILEIO_SEEK_SET);
1593 file.Fread(&whdr, sizeof(whdr), 1);
1595 uint8 subchunkname[4];
1596 fsize = 4 + whdr.chunksize - sizeof(whdr);
1599 file.Fseek(fsize, FILEIO_SEEK_CUR);
1600 file.Fread(&subchunkname, 4, 1);
1601 file.Fread(&fsize, 4, 1);
1602 } while (memcmp("data", subchunkname, 4));
1605 if (fsize >= 0x100000 || whdr.tag != 1 || whdr.nch != 1)
1607 fsize = Max(fsize, (1<<31)/1024);
1609 delete rhythm[i].sample;
1610 rhythm[i].sample = new int16[fsize];
1611 if (!rhythm[i].sample)
1614 file.Fread(rhythm[i].sample, fsize * 2, 1);
1616 rhythm[i].rate = whdr.rate;
1617 rhythm[i].step = rhythm[i].rate * 1024 / rate;
1618 rhythm[i].pos = rhythm[i].size = fsize * 1024;
1624 delete[] rhythm[i].sample;
1625 rhythm[i].sample = 0;
1634 // ---------------------------------------------------------------------------
1635 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
1637 void OPNA::SetReg(uint addr, uint data)
1645 // UpdateStatus(); //?
1648 // Rhythm ----------------------------------------------------------------
1649 case 0x10: // DM/KEYON
1650 if (!(data & 0x80)) // KEY ON
1652 rhythmkey |= data & 0x3f;
1653 if (data & 0x01) rhythm[0].pos = 0;
1654 if (data & 0x02) rhythm[1].pos = 0;
1655 if (data & 0x04) rhythm[2].pos = 0;
1656 if (data & 0x08) rhythm[3].pos = 0;
1657 if (data & 0x10) rhythm[4].pos = 0;
1658 if (data & 0x20) rhythm[5].pos = 0;
1667 rhythmtl = ~data & 63;
1670 case 0x18: // Bass Drum
1671 case 0x19: // Snare Drum
1672 case 0x1a: // Top Cymbal
1674 case 0x1c: // Tom-tom
1675 case 0x1d: // Rim shot
1676 rhythm[addr & 7].pan = (data >> 6) & 3;
1677 rhythm[addr & 7].level = ~data & 31;
1680 case 0x100: case 0x101:
1681 case 0x102: case 0x103:
1682 case 0x104: case 0x105:
1683 case 0x108: case 0x109:
1684 case 0x10a: case 0x10b:
1685 case 0x10c: case 0x10d:
1687 OPNABase::SetADPCMBReg(addr - 0x100, data);
1691 // for PC-8801FA/MA shop demonstration
1692 if ((control1 & 0x10) && (status & adpcmnotice)) {
1693 ResetStatus(adpcmnotice);
1698 OPNABase::SetReg(addr, data);
1704 // ---------------------------------------------------------------------------
1705 //
\83\8a\83Y
\83\80\8d\87\90¬
1707 void OPNA::RhythmMix(Sample* buffer, uint count)
1709 if ((rhythmtvol_l < 128 || rhythmtvol_r < 128) && rhythm[0].sample && (rhythmkey & 0x3f))
1711 Sample* limit = buffer + count * 2;
1712 for (int i=0; i<6; i++)
1714 Rhythm& r = rhythm[i];
1715 if ((rhythmkey & (1 << i)) && r.level < 128)
1717 int db_l = Limit(rhythmtl+rhythmtvol_l+r.level+r.volume_l, 127, -31);
1718 int db_r = Limit(rhythmtl+rhythmtvol_r+r.level+r.volume_r, 127, -31);
1719 int vol_l = tltable[FM_TLPOS+(db_l << (FM_TLBITS-7))] >> 4;
1720 int vol_r = tltable[FM_TLPOS+(db_r << (FM_TLBITS-7))] >> 4;
1721 int mask_l = -((r.pan >> 1) & 1);
1722 int mask_r = -(r.pan & 1);
1724 if (rhythmmask_ & (1 << i))
1726 mask_l = mask_r = 0;
1729 for (Sample* dest = buffer; dest<limit && r.pos < r.size; dest+=2)
1731 int sample_l = (r.sample[r.pos / 1024] * vol_l) >> 12;
1732 int sample_r = (r.sample[r.pos / 1024] * vol_r) >> 12;
1734 StoreSample(dest[0], sample_l & mask_l);
1735 StoreSample(dest[1], sample_r & mask_r);
1742 // ---------------------------------------------------------------------------
1745 void OPNA::SetVolumeRhythmTotal(int db_l, int db_r)
1747 db_l = Min(db_l, 20);
1748 db_r = Min(db_r, 20);
1750 rhythmtvol_l = -(db_l * 2 / 3);
1751 rhythmtvol_r = -(db_r * 2 / 3);
1754 void OPNA::SetVolumeRhythm(int index, int db_l, int db_r)
1756 db_l = Min(db_l, 20);
1757 db_r = Min(db_r, 20);
1759 rhythm[index].volume_l = -(db_l * 2 / 3);
1760 rhythm[index].volume_r = -(db_r * 2 / 3);
1763 void OPNA::SetVolumeADPCM(int db_l, int db_r)
1765 db_l = Min(db_l, 20);
1766 db_r = Min(db_r, 20);
1769 adpcmvol_l = int(65536.0 * pow(10.0, db_l / 40.0));
1773 adpcmvol_r = int(65536.0 * pow(10.0, db_r / 40.0));
1777 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
1778 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
1781 // ---------------------------------------------------------------------------
1783 // in: buffer
\8d\87\90¬
\90æ
1784 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
1786 void OPNA::Mix(Sample* buffer, int nsamples)
1788 FMMix(buffer, nsamples);
1789 psg.Mix(buffer, nsamples);
1790 ADPCMBMix(buffer, nsamples);
1791 RhythmMix(buffer, nsamples);
1794 // ---------------------------------------------------------------------------
1795 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
1797 #define OPNA_STATE_VERSION 4
1799 void OPNA::SaveState(void *f)
1801 FILEIO *state_fio = (FILEIO *)f;
1803 state_fio->FputUint32_BE(OPNA_STATE_VERSION);
1805 OPNABase::SaveState(f);
1806 for(int i = 0; i < 6; i++) {
1807 state_fio->FputUint8(rhythm[i].pan);
1808 state_fio->FputInt8(rhythm[i].level);
1809 state_fio->FputUint32_BE(rhythm[i].pos);
1811 state_fio->FputInt8(rhythmtl);
1812 state_fio->FputInt32_BE(rhythmtvol_l);
1813 state_fio->FputInt32_BE(rhythmtvol_r);
1814 state_fio->FputUint8(rhythmkey);
1817 bool OPNA::LoadState(void *f)
1819 FILEIO *state_fio = (FILEIO *)f;
1821 if(state_fio->FgetUint32_BE() != OPNA_STATE_VERSION) {
1824 if(!OPNABase::LoadState(f)) {
1827 for(int i = 0; i < 6; i++) {
1828 rhythm[i].pan = state_fio->FgetUint8();
1829 rhythm[i].level = state_fio->FgetInt8();
1830 rhythm[i].pos = state_fio->FgetUint32_BE();
1832 rhythmtl = state_fio->FgetInt8();
1833 rhythmtvol_l = state_fio->FgetInt32_BE();
1834 rhythmtvol_r = state_fio->FgetInt32_BE();
1835 rhythmkey = state_fio->FgetUint8();
1839 #endif // BUILD_OPNA
1841 // ---------------------------------------------------------------------------
1843 // ---------------------------------------------------------------------------
1847 // ---------------------------------------------------------------------------
1854 for (int i=0; i<6; i++)
1857 adpcma[i].level = 0;
1858 adpcma[i].volume_l = 0;
1859 adpcma[i].volume_r = 0;
1862 adpcma[i].start = 0;
1864 adpcma[i].adpcmx = 0;
1865 adpcma[i].adpcmd = 0;
1872 adpcmnotice = 0x8000;
1883 // ---------------------------------------------------------------------------
1886 bool OPNB::Init(uint c, uint r, bool ipflag,
1887 uint8 *_adpcma, int _adpcma_size,
1888 uint8 *_adpcmb, int _adpcmb_size)
1891 if (!SetRate(c, r, ipflag))
1893 if (!OPNABase::Init(c, r, ipflag))
1896 adpcmabuf = _adpcma;
1897 adpcmasize = _adpcma_size;
1900 for (i=0; i<=24; i++) // max 16M bytes
1902 if (_adpcmb_size <= (1 << i))
1904 adpcmmask = (1 << i) - 1;
1909 // adpcmmask = _adpcmb_size - 1;
1910 limitaddr = adpcmmask;
1916 SetVolumeADPCMB(0, 0);
1917 SetVolumeADPCMATotal(0, 0);
1919 SetVolumeADPCMA(i, 0, 0);
1924 // ---------------------------------------------------------------------------
1925 //
\83\8a\83Z
\83b
\83g
1935 for (int i=0; i<6; i++)
1938 adpcma[i].level = 0;
1939 adpcma[i].volume_l = 0;
1940 adpcma[i].volume_r = 0;
1943 adpcma[i].start = 0;
1945 adpcma[i].adpcmx = 0;
1946 adpcma[i].adpcmd = 0;
1950 // ---------------------------------------------------------------------------
1951 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
1953 bool OPNB::SetRate(uint c, uint r, bool ipflag)
1955 if (!OPNABase::SetRate(c, r, ipflag))
1958 adpcmastep = int(double(c) / 54 * 8192 / r);
1962 // ---------------------------------------------------------------------------
1963 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
1965 void OPNB::SetReg(uint addr, uint data)
1971 // omitted registers
1973 case 0x2d: case 0x2e: case 0x2f:
1976 // ADPCM A ---------------------------------------------------------------
1977 case 0x100: // DM/KEYON
1978 if (!(data & 0x80)) // KEY ON
1980 adpcmakey |= data & 0x3f;
1981 for (int c=0; c<6; c++)
1985 ResetStatus(0x100 << c);
1986 adpcma[c].pos = adpcma[c].start;
1987 // adpcma[c].step = 0x10000 - adpcma[c].step;
1989 adpcma[c].adpcmx = 0;
1990 adpcma[c].adpcmd = 0;
1991 adpcma[c].nibble = 0;
2002 adpcmatl = ~data & 63;
2005 case 0x108: case 0x109: case 0x10a:
2006 case 0x10b: case 0x10c: case 0x10d:
2007 adpcma[addr & 7].pan = (data >> 6) & 3;
2008 adpcma[addr & 7].level = ~data & 31;
2011 case 0x110: case 0x111: case 0x112: // START ADDRESS (L)
2012 case 0x113: case 0x114: case 0x115:
2013 case 0x118: case 0x119: case 0x11a: // START ADDRESS (H)
2014 case 0x11b: case 0x11c: case 0x11d:
2015 adpcmareg[addr - 0x110] = data;
2016 adpcma[addr & 7].pos = adpcma[addr & 7].start =
2017 (adpcmareg[(addr&7)+8]*256+adpcmareg[addr&7]) << 9;
2020 case 0x120: case 0x121: case 0x122: // END ADDRESS (L)
2021 case 0x123: case 0x124: case 0x125:
2022 case 0x128: case 0x129: case 0x12a: // END ADDRESS (H)
2023 case 0x12b: case 0x12c: case 0x12d:
2024 adpcmareg[addr - 0x110] = data;
2025 adpcma[addr & 7].stop =
2026 (adpcmareg[(addr&7)+24]*256+adpcmareg[(addr&7)+16] + 1) << 9;
2029 // ADPCMB -----------------------------------------------------------------
2031 if ((data & 0x80) && !adpcmplay)
2034 memaddr = startaddr;
2035 adpcmx = 0, adpcmd = 127;
2040 control1 = data & 0x91;
2044 case 0x11: // Control Register 2
2045 control2 = data & 0xc0;
2048 case 0x12: // Start Address L
2049 case 0x13: // Start Address H
2050 adpcmreg[addr - 0x12 + 0] = data;
2051 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 9;
2052 memaddr = startaddr;
2055 case 0x14: // Stop Address L
2056 case 0x15: // Stop Address H
2057 adpcmreg[addr - 0x14 + 2] = data;
2058 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 9;
2059 // LOG1(" stopaddr %.6x", stopaddr);
2062 case 0x19: // delta-N L
2063 case 0x1a: // delta-N H
2064 adpcmreg[addr - 0x19 + 4] = data;
2065 deltan = adpcmreg[5]*256+adpcmreg[4];
2066 deltan = Max(256, deltan);
2067 adpld = deltan * adplbase >> 16;
2070 case 0x1b: // Level Control
2072 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
2073 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
2076 case 0x1c: // Flag Control
2077 stmask = ~((data & 0xbf) << 8);
2083 OPNABase::SetReg(addr, data);
2089 // ---------------------------------------------------------------------------
2090 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
2092 uint OPNB::GetReg(uint addr)
2095 return psg.GetReg(addr);
2100 // ---------------------------------------------------------------------------
2101 //
\8ag
\92£
\83X
\83e
\81[
\83^
\83X
\82ð
\93Ç
\82Ý
\82±
\82Þ
2103 uint OPNB::ReadStatusEx()
2105 return (status & stmask) >> 8;
2108 // ---------------------------------------------------------------------------
2111 int OPNB::jedi_table[(48+1)*16];
2113 void OPNB::InitADPCMATable()
2115 const static int8 table2[] =
2117 1, 3, 5, 7, 9, 11, 13, 15,
2118 -1, -3, -5, -7, -9,-11,-13,-15,
2121 for (int i=0; i<=48; i++)
2123 int s = int(16.0 * pow (1.1, i) * 3);
2124 for (int j=0; j<16; j++)
2126 jedi_table[i*16+j] = s * table2[j] / 8;
2131 // ---------------------------------------------------------------------------
2132 // ADPCMA
\8d\87\90¬
2134 void OPNB::ADPCMAMix(Sample* buffer, uint count)
2136 const static int decode_tableA1[16] =
2138 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
2139 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
2142 if ((adpcmatvol_l < 128 || adpcmatvol_r < 128) && (adpcmakey & 0x3f))
2144 Sample* limit = buffer + count * 2;
2145 for (int i=0; i<6; i++)
2147 ADPCMA& r = adpcma[i];
2148 if ((adpcmakey & (1 << i)) && r.level < 128)
2150 uint mask_l = r.pan & 2 ? -1 : 0;
2151 uint mask_r = r.pan & 1 ? -1 : 0;
2152 if (rhythmmask_ & (1 << i))
2154 mask_l = mask_r = 0;
2157 int db_l = Limit(adpcmatl+adpcmatvol_l+r.level+r.volume_l, 127, -31);
2158 int db_r = Limit(adpcmatl+adpcmatvol_r+r.level+r.volume_r, 127, -31);
2159 int vol_l = tltable[FM_TLPOS+(db_l << (FM_TLBITS-7))] >> 4;
2160 int vol_r = tltable[FM_TLPOS+(db_r << (FM_TLBITS-7))] >> 4;
2162 Sample* dest = buffer;
2163 for ( ; dest<limit; dest+=2)
2165 r.step += adpcmastep;
2166 if (r.pos >= r.stop)
2168 SetStatus(0x100 << i);
2169 adpcmakey &= ~(1<<i);
2173 for (; r.step > 0x10000; r.step -= 0x10000)
2178 r.nibble = adpcmabuf[r.pos>>1];
2179 data = r.nibble >> 4;
2183 data = r.nibble & 0x0f;
2187 r.adpcmx += jedi_table[r.adpcmd + data];
2188 r.adpcmx = Limit(r.adpcmx, 2048*3-1, -2048*3);
2189 r.adpcmd += decode_tableA1[data];
2190 r.adpcmd = Limit(r.adpcmd, 48*16, 0);
2192 int sample_l = (r.adpcmx * vol_l) >> 10;
2193 int sample_r = (r.adpcmx * vol_r) >> 10;
2194 StoreSample(dest[0], sample_l & mask_l);
2195 StoreSample(dest[1], sample_r & mask_r);
2202 // ---------------------------------------------------------------------------
2205 void OPNB::SetVolumeADPCMATotal(int db_l, int db_r)
2207 db_l = Min(db_l, 20);
2208 db_r = Min(db_r, 20);
2210 adpcmatvol_l = -(db_l * 2 / 3);
2211 adpcmatvol_r = -(db_r * 2 / 3);
2214 void OPNB::SetVolumeADPCMA(int index, int db_l, int db_r)
2216 db_l = Min(db_l, 20);
2217 db_r = Min(db_r, 20);
2219 adpcma[index].volume_l = -(db_l * 2 / 3);
2220 adpcma[index].volume_r = -(db_r * 2 / 3);
2223 void OPNB::SetVolumeADPCMB(int db_l, int db_r)
2225 db_l = Min(db_l, 20);
2226 db_r = Min(db_r, 20);
2229 adpcmvol_l = int(65536.0 * pow(10.0, db_l / 40.0));
2233 adpcmvol_r = int(65536.0 * pow(10.0, db_r / 40.0));
2238 // ---------------------------------------------------------------------------
2240 // in: buffer
\8d\87\90¬
\90æ
2241 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
2243 void OPNB::Mix(Sample* buffer, int nsamples)
2245 FMMix(buffer, nsamples);
2246 psg.Mix(buffer, nsamples);
2247 ADPCMBMix(buffer, nsamples);
2248 ADPCMAMix(buffer, nsamples);
2251 #endif // BUILD_OPNB