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;
217 if(state_fio->FgetUint32_BE() != OPN_BASE_STATE_VERSION) {
220 if(!Timer::LoadState(f)) {
223 fmvolume_l = state_fio->FgetInt32_BE();
224 fmvolume_r = state_fio->FgetInt32_BE();
225 clock = state_fio->FgetUint32_BE();
226 rate = state_fio->FgetUint32_BE();
227 psgrate = state_fio->FgetUint32_BE();
228 status = state_fio->FgetUint32_BE();
229 interrupt = state_fio->FgetBool();
230 prescale = state_fio->FgetUint8();
232 // Make force-restore around prescaler and timers. 20180625 K.O
237 if(!chip.LoadState(f)) {
240 if(!psg.LoadState(f)) {
246 #endif // defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB)
248 // ---------------------------------------------------------------------------
260 for (int i=0; i<3; i++)
262 ch[i].SetChip(&chip);
263 ch[i].SetType(typeN);
268 bool OPN::Init(uint c, uint r, bool ip, const char*)
270 if (!SetRate(c, r, ip))
281 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
282 bool OPN::SetRate(uint c, uint r, bool)
290 //
\83\8a\83Z
\83b
\83g
294 for (i=0x20; i<0x28; i++) SetReg(i, 0);
295 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
303 //
\83\8c\83W
\83X
\83^
\93Ç
\82Ý
\8d\9e\82Ý
304 uint OPN::GetReg(uint addr)
307 return psg.GetReg(addr);
313 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
314 void OPN::SetReg(uint addr, uint data)
316 // LOG2("reg[%.2x] <- %.2x\n", addr, data);
323 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
324 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
325 psg.SetReg(addr, data);
328 case 0x24: case 0x25:
329 SetTimerA(addr, data);
337 SetTimerControl(data);
340 case 0x28: // Key On/Off
342 ch[data & 3].KeyControl(data >> 4);
345 case 0x2d: case 0x2e: case 0x2f:
346 SetPrescaler(addr-0x2d);
350 case 0xa0: case 0xa1: case 0xa2:
351 fnum[c] = data + fnum2[c] * 0x100;
354 case 0xa4: case 0xa5: case 0xa6:
355 fnum2[c] = uint8(data);
358 case 0xa8: case 0xa9: case 0xaa:
359 fnum3[c] = data + fnum2[c+3] * 0x100;
362 case 0xac: case 0xad: case 0xae:
363 fnum2[c+3] = uint8(data);
366 case 0xb0: case 0xb1: case 0xb2:
367 ch[c].SetFB((data >> 3) & 7);
368 ch[c].SetAlgorithm(data & 7);
374 if ((addr & 0xf0) == 0x60)
376 OPNBase::SetParameter(&ch[c], addr, data);
382 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
383 void OPN::SetStatus(uint bits)
385 if (!(status & bits))
392 void OPN::ResetStatus(uint bit)
399 //
\83}
\83X
\83N
\90Ý
\92è
400 void OPN::SetChannelMask(uint mask)
402 for (int i=0; i<3; i++)
403 ch[i].Mute(!!(mask & (1 << i)));
404 psg.SetChannelMask(mask >> 6);
409 void OPN::Mix(Sample* buffer, int nsamples)
411 #define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
412 #define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
414 psg.Mix(buffer, nsamples);
417 ch[0].SetFNum(fnum[0]);
418 ch[1].SetFNum(fnum[1]);
420 ch[2].SetFNum(fnum[2]);
423 ch[2].op[0].SetFNum(fnum3[1]);
424 ch[2].op[1].SetFNum(fnum3[2]);
425 ch[2].op[2].SetFNum(fnum3[0]);
426 ch[2].op[3].SetFNum(fnum[2]);
429 int actch = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
432 Sample* limit = buffer + nsamples * 2;
433 for (Sample* dest = buffer; dest < limit; dest+=2)
437 if (actch & 0x01) s = ch[0].Calc();
438 if (actch & 0x04) s += ch[1].Calc();
439 if (actch & 0x10) s += ch[2].Calc();
440 s_l = IStoSampleL(s);
441 s_r = IStoSampleR(s);
442 StoreSample(dest[0], s_l);
443 StoreSample(dest[1], s_r);
450 // ---------------------------------------------------------------------------
451 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
453 #define OPN_STATE_VERSION 2
455 void OPN::SaveState(void *f)
457 FILEIO *state_fio = (FILEIO *)f;
459 state_fio->FputUint32_BE(OPN_STATE_VERSION);
461 OPNBase::SaveState(f);
462 for(int i = 0; i < 3; i++) {
463 state_fio->FputUint32_BE(fnum[i]);
465 for(int i = 0; i < 3; i++) {
466 state_fio->FputUint32_BE(fnum3[i]);
468 //state_fio->Fwrite(fnum, sizeof(fnum), 1);
469 //state_fio->Fwrite(fnum3, sizeof(fnum3), 1);
470 state_fio->Fwrite(fnum2, sizeof(fnum2), 1);
471 for(int i = 0; i < 3; i++) {
476 bool OPN::LoadState(void *f)
478 FILEIO *state_fio = (FILEIO *)f;
480 if(state_fio->FgetUint32_BE() != OPN_STATE_VERSION) {
483 if(!OPNBase::LoadState(f)) {
486 for(int i = 0; i < 3; i++) {
487 fnum[i] = state_fio->FgetUint32_BE();
489 for(int i = 0; i < 3; i++) {
490 fnum3[i] = state_fio->FgetUint32_BE();
492 //state_fio->Fread(fnum, sizeof(fnum), 1);
493 //state_fio->Fread(fnum3, sizeof(fnum3), 1);
494 state_fio->Fread(fnum2, sizeof(fnum2), 1);
495 for(int i = 0; i < 3; i++) {
496 if(!ch[i].LoadState(f)) {
505 // ---------------------------------------------------------------------------
506 // YM2608/2610 common part
507 // ---------------------------------------------------------------------------
509 #if defined(BUILD_OPNA) || defined(BUILD_OPNB)
511 int OPNABase::amtable[FM_LFOENTS] = { -1, };
512 int OPNABase::pmtable[FM_LFOENTS];
514 int32 OPNABase::tltable[FM_TLENTS+FM_TLPOS];
515 bool OPNABase::tablehasmade = false;
530 for (int i=0; i<6; i++)
532 ch[i].SetChip(&chip);
533 ch[i].SetType(typeN);
537 OPNABase::~OPNABase()
541 // ---------------------------------------------------------------------------
544 bool OPNABase::Init(uint c, uint r, bool)
556 // ---------------------------------------------------------------------------
557 //
\83e
\81[
\83u
\83\8b\8dì
\90¬
559 void OPNABase::MakeTable2()
563 for (int i=-FM_TLPOS; i<FM_TLENTS; i++)
565 tltable[i+FM_TLPOS] = uint(65536. * pow(2.0, i * -16. / FM_TLENTS))-1;
572 // ---------------------------------------------------------------------------
573 //
\83\8a\83Z
\83b
\83g
575 void OPNABase::Reset()
580 for (i=0x20; i<0x28; i++) SetReg(i, 0);
581 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
582 for (i=0x130; i<0x1c0; i++) SetReg(i, 0);
583 for (i=0x100; i<0x110; i++) SetReg(i, 0);
584 for (i=0x10; i<0x20; i++) SetReg(i, 0);
598 apout0_l = apout1_l = adpcmout_l = 0;
599 apout0_r = apout1_r = adpcmout_r = 0;
608 // ---------------------------------------------------------------------------
609 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
611 bool OPNABase::SetRate(uint c, uint r, bool)
613 c /= 2; //
\8f]
\97\88\94Å
\82Æ
\82Ì
\8cÝ
\8a·
\90«
\82ð
\8fd
\8e\8b\82µ
\82½
\82¯
\82è
\82á
\83R
\83\81\83\93\83g
\83A
\83E
\83g
\82µ
\82æ
\82¤
617 adplbase = int(8192. * (clock/72.) / r);
618 adpld = deltan * adplbase >> 16;
622 lfodcount = reg22 & 0x08 ? lfotable[reg22 & 7] : 0;
627 // ---------------------------------------------------------------------------
628 //
\83`
\83\83\83\93\83l
\83\8b\83}
\83X
\83N
\82Ì
\90Ý
\92è
630 void OPNABase::SetChannelMask(uint mask)
632 for (int i=0; i<6; i++)
633 ch[i].Mute(!!(mask & (1 << i)));
634 psg.SetChannelMask(mask >> 6);
635 adpcmmask_ = (mask & (1 << 9)) != 0;
636 rhythmmask_ = (mask >> 10) & ((1 << 6) - 1);
639 // ---------------------------------------------------------------------------
640 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
642 void OPNABase::SetReg(uint addr, uint data)
649 // Timer -----------------------------------------------------------------
650 case 0x24: case 0x25:
651 SetTimerA(addr, data);
659 SetTimerControl(data);
662 // Misc ------------------------------------------------------------------
663 case 0x28: // Key On/Off
666 c = (data & 3) + (data & 4 ? 3 : 0);
667 ch[c].KeyControl(data >> 4);
671 // Status Mask -----------------------------------------------------------
674 // UpdateStatus(); //?
677 // Prescaler -------------------------------------------------------------
678 case 0x2d: case 0x2e: case 0x2f:
679 SetPrescaler(addr-0x2d);
682 // F-Number --------------------------------------------------------------
683 case 0x1a0: case 0x1a1: case 0x1a2:
685 case 0xa0: case 0xa1: case 0xa2:
686 fnum[c] = data + fnum2[c] * 0x100;
687 ch[c].SetFNum(fnum[c]);
690 case 0x1a4: case 0x1a5: case 0x1a6:
692 case 0xa4 : case 0xa5: case 0xa6:
693 fnum2[c] = uint8(data);
696 case 0xa8: case 0xa9: case 0xaa:
697 fnum3[c] = data + fnum2[c+6] * 0x100;
700 case 0xac : case 0xad: case 0xae:
701 fnum2[c+6] = uint8(data);
704 // Algorithm -------------------------------------------------------------
706 case 0x1b0: case 0x1b1: case 0x1b2:
708 case 0xb0: case 0xb1: case 0xb2:
709 ch[c].SetFB((data >> 3) & 7);
710 ch[c].SetAlgorithm(data & 7);
713 case 0x1b4: case 0x1b5: case 0x1b6:
715 case 0xb4: case 0xb5: case 0xb6:
716 pan[c] = (data >> 6) & 3;
720 // LFO -------------------------------------------------------------------
722 modified = reg22 ^ data;
726 lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0;
729 // PSG -------------------------------------------------------------------
730 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
731 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
732 psg.SetReg(addr, data);
735 //
\89¹
\90F ------------------------------------------------------------------
741 OPNBase::SetParameter(&ch[c], addr, data);
747 // ---------------------------------------------------------------------------
750 void OPNABase::SetADPCMBReg(uint addr, uint data)
754 case 0x00: // Control Register 1
755 if ((data & 0x80) && !adpcmplay)
759 adpcmx = 0, adpcmd = 127;
769 case 0x01: // Control Register 2
771 granuality = control2 & 2 ? 1 : 4;
774 case 0x02: // Start Address L
775 case 0x03: // Start Address H
776 adpcmreg[addr - 0x02 + 0] = data;
777 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 6;
779 // LOG1(" startaddr %.6x", startaddr);
782 case 0x04: // Stop Address L
783 case 0x05: // Stop Address H
784 adpcmreg[addr - 0x04 + 2] = data;
785 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 6;
786 // LOG1(" stopaddr %.6x", stopaddr);
789 case 0x08: // ADPCM data
790 if ((control1 & 0x60) == 0x60)
792 // LOG2(" Wr [0x%.5x] = %.2x", memaddr, data);
797 case 0x09: // delta-N L
798 case 0x0a: // delta-N H
799 adpcmreg[addr - 0x09 + 4] = data;
800 deltan = adpcmreg[5]*256+adpcmreg[4];
801 deltan = Max(256, deltan);
802 adpld = deltan * adplbase >> 16;
805 case 0x0b: // Level Control
807 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
808 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
811 case 0x0c: // Limit Address L
812 case 0x0d: // Limit Address H
813 adpcmreg[addr - 0x0c + 6] = data;
814 limitaddr = (adpcmreg[7]*256+adpcmreg[6] + 1) << 6;
815 // LOG1(" limitaddr %.6x", limitaddr);
818 case 0x10: // Flag Control
821 // for Firecracker Music collection (Hi-speed PCM loader)
827 stmask = ~(data & 0x1f);
828 // UpdateStatus(); //???
835 // ---------------------------------------------------------------------------
836 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
838 uint OPNA::GetReg(uint addr)
841 return psg.GetReg(addr);
845 // LOG1("%d:reg[108] -> ", Diag::GetCPUTick());
847 uint data = adpcmreadbuf & 0xff;
849 if ((control1 & 0x60) == 0x20)
851 adpcmreadbuf |= ReadRAM() << 8;
852 // LOG2("Rd [0x%.6x:%.2x] ", memaddr, adpcmreadbuf >> 8);
867 // ---------------------------------------------------------------------------
868 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
870 void OPNABase::SetStatus(uint bits)
872 if (!(status & bits))
874 // LOG2("SetStatus(%.2x %.2x)\n", bits, stmask);
875 status |= bits & stmask;
879 // LOG1("SetStatus(%.2x) - ignored\n", bits);
882 void OPNABase::ResetStatus(uint bits)
885 // LOG1("ResetStatus(%.2x)\n", bits);
889 inline void OPNABase::UpdateStatus()
891 // LOG2("%d:INT = %d\n", Diag::GetCPUTick(), (status & stmask & reg29) != 0);
892 Intr((status & stmask & reg29) != 0);
895 // ---------------------------------------------------------------------------
896 // ADPCM RAM
\82Ö
\82Ì
\8f\91\8d\9e\82Ý
\91\80\8dì
898 void OPNABase::WriteRAM(uint data)
900 #ifndef NO_BITTYPE_EMULATION
904 adpcmbuf[(memaddr >> 4) & 0x3ffff] = data;
910 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
911 uint bank = (memaddr >> 1) & 7;
912 uint8 mask = 1 << bank;
915 p[0x00000] = (p[0x00000] & ~mask) | (uint8(data) & mask); data >>= 1;
916 p[0x08000] = (p[0x08000] & ~mask) | (uint8(data) & mask); data >>= 1;
917 p[0x10000] = (p[0x10000] & ~mask) | (uint8(data) & mask); data >>= 1;
918 p[0x18000] = (p[0x18000] & ~mask) | (uint8(data) & mask); data >>= 1;
919 p[0x20000] = (p[0x20000] & ~mask) | (uint8(data) & mask); data >>= 1;
920 p[0x28000] = (p[0x28000] & ~mask) | (uint8(data) & mask); data >>= 1;
921 p[0x30000] = (p[0x30000] & ~mask) | (uint8(data) & mask); data >>= 1;
922 p[0x38000] = (p[0x38000] & ~mask) | (uint8(data) & mask);
926 adpcmbuf[(memaddr >> granuality) & 0x3ffff] = data;
927 memaddr += 1 << granuality;
930 if (memaddr == stopaddr)
933 statusnext = 0x04; // EOS
936 if (memaddr == limitaddr)
938 // LOG1("Limit ! (%.8x)\n", limitaddr);
944 // ---------------------------------------------------------------------------
945 // ADPCM RAM
\82©
\82ç
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
\91\80\8dì
947 uint OPNABase::ReadRAM()
950 #ifndef NO_BITTYPE_EMULATION
954 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
960 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
961 uint bank = (memaddr >> 1) & 7;
962 uint8 mask = 1 << bank;
964 data = (p[0x38000] & mask);
965 data = data * 2 + (p[0x30000] & mask);
966 data = data * 2 + (p[0x28000] & mask);
967 data = data * 2 + (p[0x20000] & mask);
968 data = data * 2 + (p[0x18000] & mask);
969 data = data * 2 + (p[0x10000] & mask);
970 data = data * 2 + (p[0x08000] & mask);
971 data = data * 2 + (p[0x00000] & mask);
976 data = adpcmbuf[(memaddr >> granuality) & 0x3ffff];
977 memaddr += 1 << granuality;
979 if (memaddr == stopaddr)
982 statusnext = 0x04; // EOS
985 if (memaddr == limitaddr)
987 // LOG1("Limit ! (%.8x)\n", limitaddr);
990 if (memaddr < stopaddr)
996 inline int OPNABase::DecodeADPCMBSample(uint data)
998 static const int table1[16] =
1000 1, 3, 5, 7, 9, 11, 13, 15,
1001 -1, -3, -5, -7, -9, -11, -13, -15,
1003 static const int table2[16] =
1005 57, 57, 57, 57, 77, 102, 128, 153,
1006 57, 57, 57, 57, 77, 102, 128, 153,
1008 adpcmx = Limit(adpcmx + table1[data] * adpcmd / 8, 32767, -32768);
1009 adpcmd = Limit(adpcmd * table2[data] / 64, 24576, 127);
1014 // ---------------------------------------------------------------------------
1015 // ADPCM RAM
\82©
\82ç
\82Ì nibble
\93Ç
\82Ý
\8d\9e\82Ý
\8by
\82Ñ ADPCM
\93W
\8aJ
1017 int OPNABase::ReadRAMN()
1022 #ifndef NO_BITTYPE_EMULATION
1023 if (!(control2 & 2))
1025 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
1028 return DecodeADPCMBSample(data >> 4);
1033 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff] + ((~memaddr & 1) << 17);
1034 uint bank = (memaddr >> 1) & 7;
1035 uint8 mask = 1 << bank;
1037 data = (p[0x18000] & mask);
1038 data = data * 2 + (p[0x10000] & mask);
1039 data = data * 2 + (p[0x08000] & mask);
1040 data = data * 2 + (p[0x00000] & mask);
1044 return DecodeADPCMBSample(data);
1047 data = adpcmbuf[(memaddr >> granuality) & adpcmmask];
1048 memaddr += 1 << (granuality-1);
1049 if (memaddr & (1 << (granuality-1)))
1050 return DecodeADPCMBSample(data >> 4);
1056 data = adpcmbuf[(memaddr >> 1) & adpcmmask];
1059 return DecodeADPCMBSample(data >> 4);
1063 DecodeADPCMBSample(data);
1066 if (memaddr == stopaddr)
1068 if (control1 & 0x10)
1070 memaddr = startaddr;
1072 adpcmx = 0, adpcmd = 127;
1073 // for PC-8801FA/MA shop demonstration
1074 SetStatus(adpcmnotice);
1079 memaddr &= adpcmmask; //0x3fffff;
1080 SetStatus(adpcmnotice);
1085 if (memaddr == limitaddr)
1091 // ---------------------------------------------------------------------------
1092 //
\8ag
\92£
\83X
\83e
\81[
\83^
\83X
\82ð
\93Ç
\82Ý
\82±
\82Þ
1094 uint OPNABase::ReadStatusEx()
1096 uint r = ((status | 8) & stmask) | (adpcmplay ? 0x20 : 0);
1097 status |= statusnext;
1102 // ---------------------------------------------------------------------------
1105 inline void OPNABase::DecodeADPCMB()
1107 apout0_l = apout1_l;
1108 apout0_r = apout1_r;
1109 int ram = ReadRAMN();
1110 int s_l = (ram * adpcmvolume_l) >> 13;
1111 int s_r = (ram * adpcmvolume_r) >> 13;
1112 apout1_l = adpcmout_l + s_l;
1113 apout1_r = adpcmout_r + s_r;
1118 // ---------------------------------------------------------------------------
1121 void OPNABase::ADPCMBMix(Sample* dest, uint count)
1123 uint mask_l = control2 & 0x80 ? -1 : 0;
1124 uint mask_r = control2 & 0x40 ? -1 : 0;
1127 mask_l = mask_r = 0;
1132 // LOG2("ADPCM Play: %d DeltaN: %d\n", adpld, deltan);
1133 if (adpld <= 8192) // fplay < fsamp
1135 for (; count>0; count--)
1144 int s_l = (adplc * apout0_l + (8192-adplc) * apout1_l) >> 13;
1145 int s_r = (adplc * apout0_r + (8192-adplc) * apout1_r) >> 13;
1146 StoreSample(dest[0], s_l & mask_l);
1147 StoreSample(dest[1], s_r & mask_r);
1151 for (; count>0 && (apout0_l || apout0_r); count--)
1155 apout0_l = apout1_l, apout1_l = 0;
1156 apout0_r = apout1_r, apout1_r = 0;
1159 int s_l = (adplc * apout1_l) >> 13;
1160 int s_r = (adplc * apout1_r) >> 13;
1161 StoreSample(dest[0], s_l & mask_l);
1162 StoreSample(dest[1], s_r & mask_r);
1167 else // fplay > fsamp (adpld = fplay/famp*8192)
1169 int t = (-8192*8192)/adpld;
1170 for (; count>0; count--)
1172 int s_l = apout0_l * (8192+adplc);
1173 int s_r = apout0_r * (8192+adplc);
1179 s_l -= apout0_l * Max(adplc, t);
1180 s_r -= apout0_r * Max(adplc, t);
1186 StoreSample(dest[0], s_l & mask_l);
1187 StoreSample(dest[1], s_r & mask_r);
1196 apout0_l = apout1_l = adpcmout_l = 0;
1197 apout0_r = apout1_r = adpcmout_r = 0;
1202 // ---------------------------------------------------------------------------
1204 // in: buffer
\8d\87\90¬
\90æ
1205 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
1207 void OPNABase::FMMix(Sample* buffer, int nsamples)
1209 if (fmvolume_l > 0 || fmvolume_r > 0)
1213 if (!(regtc & 0xc0))
1214 csmch->SetFNum(fnum[csmch-ch]);
1217 //
\8cø
\89Ê
\89¹
\83\82\81[
\83h
1218 csmch->op[0].SetFNum(fnum3[1]); csmch->op[1].SetFNum(fnum3[2]);
1219 csmch->op[2].SetFNum(fnum3[0]); csmch->op[3].SetFNum(fnum[2]);
1222 int act = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
1224 act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6;
1225 if (!(reg22 & 0x08))
1230 Mix6(buffer, nsamples, act);
1235 // ---------------------------------------------------------------------------
1237 void OPNABase::MixSubSL(int activech, ISample** dest)
1239 if (activech & 0x001) (*dest[0] = ch[0].CalcL());
1240 if (activech & 0x004) (*dest[1] += ch[1].CalcL());
1241 if (activech & 0x010) (*dest[2] += ch[2].CalcL());
1242 if (activech & 0x040) (*dest[3] += ch[3].CalcL());
1243 if (activech & 0x100) (*dest[4] += ch[4].CalcL());
1244 if (activech & 0x400) (*dest[5] += ch[5].CalcL());
1247 inline void OPNABase::MixSubS(int activech, ISample** dest)
1249 if (activech & 0x001) (*dest[0] = ch[0].Calc());
1250 if (activech & 0x004) (*dest[1] += ch[1].Calc());
1251 if (activech & 0x010) (*dest[2] += ch[2].Calc());
1252 if (activech & 0x040) (*dest[3] += ch[3].Calc());
1253 if (activech & 0x100) (*dest[4] += ch[4].Calc());
1254 if (activech & 0x400) (*dest[5] += ch[5].Calc());
1257 // ---------------------------------------------------------------------------
1259 void OPNABase::BuildLFOTable()
1261 if (amtable[0] == -1)
1263 for (int c=0; c<256; c++)
1266 if (c < 0x40) v = c * 2 + 0x80;
1267 else if (c < 0xc0) v = 0x7f - (c - 0x40) * 2 + 0x80;
1268 else v = (c - 0xc0) * 2;
1271 if (c < 0x80) v = 0xff - c * 2;
1272 else v = (c - 0x80) * 2;
1273 amtable[c] = v & ~3;
1278 // ---------------------------------------------------------------------------
1280 inline void OPNABase::LFO()
1282 // LOG3("%4d - %8d, %8d\n", c, lfocount, lfodcount);
1284 // Operator::SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1285 // Operator::SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1286 chip.SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1287 chip.SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1288 lfocount += lfodcount;
1291 // ---------------------------------------------------------------------------
1294 #define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
1295 #define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
1297 void OPNABase::Mix6(Sample* buffer, int nsamples, int activech)
1302 idest[0] = &ibuf[pan[0]];
1303 idest[1] = &ibuf[pan[1]];
1304 idest[2] = &ibuf[pan[2]];
1305 idest[3] = &ibuf[pan[3]];
1306 idest[4] = &ibuf[pan[4]];
1307 idest[5] = &ibuf[pan[5]];
1309 Sample* limit = buffer + nsamples * 2;
1310 for (Sample* dest = buffer; dest < limit; dest+=2)
1312 ibuf[1] = ibuf[2] = ibuf[3] = 0;
1313 if (activech & 0xaaa)
1314 LFO(), MixSubSL(activech, idest);
1316 MixSubS(activech, idest);
1317 StoreSample(dest[0], IStoSampleL(ibuf[2] + ibuf[3]));
1318 StoreSample(dest[1], IStoSampleR(ibuf[1] + ibuf[3]));
1322 // ---------------------------------------------------------------------------
1323 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
1325 #define OPNA_BASE_STATE_VERSION 2
1327 void OPNABase::SaveState(void *f)
1329 FILEIO *state_fio = (FILEIO *)f;
1331 state_fio->FputUint32_BE(OPNA_BASE_STATE_VERSION);
1333 OPNBase::SaveState(f);
1334 state_fio->Fwrite(pan, sizeof(pan), 1);
1335 state_fio->Fwrite(fnum2, sizeof(fnum2), 1);
1336 state_fio->FputUint8(reg22);
1337 state_fio->FputUint32_BE(reg29);
1338 state_fio->FputUint32_BE(stmask);
1339 state_fio->FputUint32_BE(statusnext);
1340 state_fio->FputUint32_BE(lfocount);
1341 state_fio->FputUint32_BE(lfodcount);
1342 //state_fio->Fwrite(fnum, sizeof(fnum), 1);
1343 //state_fio->Fwrite(fnum3, sizeof(fnum3), 1);
1344 for(int i = 0; i < 6; i++) {
1345 state_fio->FputUint32_BE(fnum[i]);
1347 for(int i = 0; i < 3; i++) {
1348 state_fio->FputUint32_BE(fnum3[i]);
1350 state_fio->Fwrite(adpcmbuf, 0x40000, 1);
1351 state_fio->FputUint32_BE(adpcmmask);
1352 state_fio->FputUint32_BE(adpcmnotice);
1353 state_fio->FputUint32_BE(startaddr);
1354 state_fio->FputUint32_BE(stopaddr);
1355 state_fio->FputUint32_BE(memaddr);
1356 state_fio->FputUint32_BE(limitaddr);
1357 state_fio->FputInt32_BE(adpcmlevel);
1358 state_fio->FputInt32_BE(adpcmvolume_l);
1359 state_fio->FputInt32_BE(adpcmvolume_r);
1360 state_fio->FputInt32_BE(adpcmvol_l);
1361 state_fio->FputInt32_BE(adpcmvol_r);
1362 state_fio->FputUint32_BE(deltan);
1363 state_fio->FputInt32_BE(adplc);
1364 state_fio->FputInt32_BE(adpld);
1365 state_fio->FputUint32_BE(adplbase);
1366 state_fio->FputInt32_BE(adpcmx);
1367 state_fio->FputInt32_BE(adpcmd);
1368 state_fio->FputInt32_BE(adpcmout_l);
1369 state_fio->FputInt32_BE(adpcmout_r);
1370 state_fio->FputInt32_BE(apout0_l);
1371 state_fio->FputInt32_BE(apout0_r);
1372 state_fio->FputInt32_BE(apout1_l);
1373 state_fio->FputInt32_BE(apout1_r);
1374 state_fio->FputUint32_BE(adpcmreadbuf);
1375 state_fio->FputBool(adpcmplay);
1376 state_fio->FputInt8(granuality);
1377 state_fio->FputBool(adpcmmask_);
1378 state_fio->FputUint8(control1);
1379 state_fio->FputUint8(control2);
1380 state_fio->Fwrite(adpcmreg, sizeof(adpcmreg), 1);
1381 state_fio->FputInt32_BE(rhythmmask_);
1382 for(int i = 0; i < 6; i++) {
1387 bool OPNABase::LoadState(void *f)
1389 FILEIO *state_fio = (FILEIO *)f;
1391 if(state_fio->FgetUint32_BE() != OPNA_BASE_STATE_VERSION) {
1394 if(!OPNBase::LoadState(f)) {
1397 state_fio->Fread(pan, sizeof(pan), 1);
1398 state_fio->Fread(fnum2, sizeof(fnum2), 1);
1399 reg22 = state_fio->FgetUint8();
1400 reg29 = state_fio->FgetUint32_BE();
1401 stmask = state_fio->FgetUint32_BE();
1402 statusnext = state_fio->FgetUint32_BE();
1403 lfocount = state_fio->FgetUint32_BE();
1404 lfodcount = state_fio->FgetUint32_BE();
1405 //state_fio->Fread(fnum, sizeof(fnum), 1);
1406 //state_fio->Fread(fnum3, sizeof(fnum3), 1);
1407 for(int i = 0; i < 6; i++) {
1408 fnum[i] = state_fio->FgetUint32_BE();
1410 for(int i = 0; i < 3; i++) {
1411 fnum3[i] = state_fio->FgetUint32_BE();
1413 state_fio->Fread(adpcmbuf, 0x40000, 1);
1414 adpcmmask = state_fio->FgetUint32_BE();
1415 adpcmnotice = state_fio->FgetUint32_BE();
1416 startaddr = state_fio->FgetUint32_BE();
1417 stopaddr = state_fio->FgetUint32_BE();
1418 memaddr = state_fio->FgetUint32_BE();
1419 limitaddr = state_fio->FgetUint32_BE();
1420 adpcmlevel = state_fio->FgetInt32_BE();
1421 adpcmvolume_l = state_fio->FgetInt32_BE();
1422 adpcmvolume_r = state_fio->FgetInt32_BE();
1423 adpcmvol_l = state_fio->FgetInt32_BE();
1424 adpcmvol_r = state_fio->FgetInt32_BE();
1425 deltan = state_fio->FgetUint32_BE();
1426 adplc = state_fio->FgetInt32_BE();
1427 adpld = state_fio->FgetInt32_BE();
1428 adplbase = state_fio->FgetUint32_BE();
1429 adpcmx = state_fio->FgetInt32_BE();
1430 adpcmd = state_fio->FgetInt32_BE();
1431 adpcmout_l = state_fio->FgetInt32_BE();
1432 adpcmout_r = state_fio->FgetInt32_BE();
1433 apout0_l = state_fio->FgetInt32_BE();
1434 apout0_r = state_fio->FgetInt32_BE();
1435 apout1_l = state_fio->FgetInt32_BE();
1436 apout1_r = state_fio->FgetInt32_BE();
1437 adpcmreadbuf = state_fio->FgetUint32_BE();
1438 adpcmplay = state_fio->FgetBool();
1439 granuality = state_fio->FgetInt8();
1440 adpcmmask_ = state_fio->FgetBool();
1441 control1 = state_fio->FgetUint8();
1442 control2 = state_fio->FgetUint8();
1443 state_fio->Fread(adpcmreg, sizeof(adpcmreg), 1);
1444 rhythmmask_ = state_fio->FgetInt32_BE();
1445 for(int i = 0; i < 6; i++) {
1446 if(!ch[i].LoadState(f)) {
1453 #endif // defined(BUILD_OPNA) || defined(BUILD_OPNB)
1455 // ---------------------------------------------------------------------------
1457 // ---------------------------------------------------------------------------
1461 // ---------------------------------------------------------------------------
1466 for (int i=0; i<6; i++)
1468 rhythm[i].sample = 0;
1471 rhythm[i].volume_l = 0;
1472 rhythm[i].volume_r = 0;
1473 rhythm[i].level = 0;
1478 adpcmmask = 0x3ffff;
1483 // ---------------------------------------------------------------------------
1488 for (int i=0; i<6; i++)
1489 delete[] rhythm[i].sample;
1494 // ---------------------------------------------------------------------------
1497 bool OPNA::Init(uint c, uint r, bool ipflag, const _TCHAR* path)
1500 LoadRhythmSample(path);
1503 adpcmbuf = new uint8[0x40000];
1507 if (!SetRate(c, r, ipflag))
1509 if (!OPNABase::Init(c, r, ipflag))
1514 SetVolumeADPCM(0, 0);
1515 SetVolumeRhythmTotal(0, 0);
1516 for (int i=0; i<6; i++)
1517 SetVolumeRhythm(i, 0, 0);
1521 // ---------------------------------------------------------------------------
1522 //
\83\8a\83Z
\83b
\83g
1529 limitaddr = 0x3ffff;
1533 // ---------------------------------------------------------------------------
1534 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
1536 bool OPNA::SetRate(uint c, uint r, bool ipflag)
1538 if (!OPNABase::SetRate(c, r, ipflag))
1541 for (int i=0; i<6; i++)
1543 rhythm[i].step = rhythm[i].rate * 1024 / r;
1549 // ---------------------------------------------------------------------------
1550 //
\83\8a\83Y
\83\80\89¹
\82ð
\93Ç
\82Ý
\82±
\82Þ
1552 bool OPNA::LoadRhythmSample(const _TCHAR* path)
1554 static const _TCHAR* rhythmname[6] =
1556 _T("BD"), _T("SD"), _T("TOP"), _T("HH"), _T("TOM"), _T("RIM"),
1567 _TCHAR buf[_MAX_PATH] = _T("");
1569 _tcsncpy(buf, path, _MAX_PATH);
1570 _tcsncat(buf, _T("2608_"), _MAX_PATH);
1571 _tcsncat(buf, rhythmname[i], _MAX_PATH);
1572 _tcsncat(buf, _T(".WAV"), _MAX_PATH);
1574 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1579 _tcsncpy(buf, path, _MAX_PATH);
1580 _tcsncpy(buf, _T("2608_RYM.WAV"), _MAX_PATH);
1581 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1597 file.Fseek(0x10, FILEIO_SEEK_SET);
1598 file.Fread(&whdr, sizeof(whdr), 1);
1600 uint8 subchunkname[4];
1601 fsize = 4 + whdr.chunksize - sizeof(whdr);
1604 file.Fseek(fsize, FILEIO_SEEK_CUR);
1605 file.Fread(&subchunkname, 4, 1);
1606 file.Fread(&fsize, 4, 1);
1607 } while (memcmp("data", subchunkname, 4));
1610 if (fsize >= 0x100000 || whdr.tag != 1 || whdr.nch != 1)
1612 fsize = Max(fsize, (1<<31)/1024);
1614 delete rhythm[i].sample;
1615 rhythm[i].sample = new int16[fsize];
1616 if (!rhythm[i].sample)
1619 file.Fread(rhythm[i].sample, fsize * 2, 1);
1621 rhythm[i].rate = whdr.rate;
1622 rhythm[i].step = rhythm[i].rate * 1024 / rate;
1623 rhythm[i].pos = rhythm[i].size = fsize * 1024;
1629 delete[] rhythm[i].sample;
1630 rhythm[i].sample = 0;
1639 // ---------------------------------------------------------------------------
1640 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
1642 void OPNA::SetReg(uint addr, uint data)
1650 // UpdateStatus(); //?
1653 // Rhythm ----------------------------------------------------------------
1654 case 0x10: // DM/KEYON
1655 if (!(data & 0x80)) // KEY ON
1657 rhythmkey |= data & 0x3f;
1658 if (data & 0x01) rhythm[0].pos = 0;
1659 if (data & 0x02) rhythm[1].pos = 0;
1660 if (data & 0x04) rhythm[2].pos = 0;
1661 if (data & 0x08) rhythm[3].pos = 0;
1662 if (data & 0x10) rhythm[4].pos = 0;
1663 if (data & 0x20) rhythm[5].pos = 0;
1672 rhythmtl = ~data & 63;
1675 case 0x18: // Bass Drum
1676 case 0x19: // Snare Drum
1677 case 0x1a: // Top Cymbal
1679 case 0x1c: // Tom-tom
1680 case 0x1d: // Rim shot
1681 rhythm[addr & 7].pan = (data >> 6) & 3;
1682 rhythm[addr & 7].level = ~data & 31;
1685 case 0x100: case 0x101:
1686 case 0x102: case 0x103:
1687 case 0x104: case 0x105:
1688 case 0x108: case 0x109:
1689 case 0x10a: case 0x10b:
1690 case 0x10c: case 0x10d:
1692 OPNABase::SetADPCMBReg(addr - 0x100, data);
1696 // for PC-8801FA/MA shop demonstration
1697 if ((control1 & 0x10) && (status & adpcmnotice)) {
1698 ResetStatus(adpcmnotice);
1703 OPNABase::SetReg(addr, data);
1709 // ---------------------------------------------------------------------------
1710 //
\83\8a\83Y
\83\80\8d\87\90¬
1712 void OPNA::RhythmMix(Sample* buffer, uint count)
1714 if ((rhythmtvol_l < 128 || rhythmtvol_r < 128) && rhythm[0].sample && (rhythmkey & 0x3f))
1716 Sample* limit = buffer + count * 2;
1717 for (int i=0; i<6; i++)
1719 Rhythm& r = rhythm[i];
1720 if ((rhythmkey & (1 << i)) && r.level < 128)
1722 int db_l = Limit(rhythmtl+rhythmtvol_l+r.level+r.volume_l, 127, -31);
1723 int db_r = Limit(rhythmtl+rhythmtvol_r+r.level+r.volume_r, 127, -31);
1724 int vol_l = tltable[FM_TLPOS+(db_l << (FM_TLBITS-7))] >> 4;
1725 int vol_r = tltable[FM_TLPOS+(db_r << (FM_TLBITS-7))] >> 4;
1726 int mask_l = -((r.pan >> 1) & 1);
1727 int mask_r = -(r.pan & 1);
1729 if (rhythmmask_ & (1 << i))
1731 mask_l = mask_r = 0;
1734 for (Sample* dest = buffer; dest<limit && r.pos < r.size; dest+=2)
1736 int sample_l = (r.sample[r.pos / 1024] * vol_l) >> 12;
1737 int sample_r = (r.sample[r.pos / 1024] * vol_r) >> 12;
1739 StoreSample(dest[0], sample_l & mask_l);
1740 StoreSample(dest[1], sample_r & mask_r);
1747 // ---------------------------------------------------------------------------
1750 void OPNA::SetVolumeRhythmTotal(int db_l, int db_r)
1752 db_l = Min(db_l, 20);
1753 db_r = Min(db_r, 20);
1755 rhythmtvol_l = -(db_l * 2 / 3);
1756 rhythmtvol_r = -(db_r * 2 / 3);
1759 void OPNA::SetVolumeRhythm(int index, int db_l, int db_r)
1761 db_l = Min(db_l, 20);
1762 db_r = Min(db_r, 20);
1764 rhythm[index].volume_l = -(db_l * 2 / 3);
1765 rhythm[index].volume_r = -(db_r * 2 / 3);
1768 void OPNA::SetVolumeADPCM(int db_l, int db_r)
1770 db_l = Min(db_l, 20);
1771 db_r = Min(db_r, 20);
1774 adpcmvol_l = int(65536.0 * pow(10.0, db_l / 40.0));
1778 adpcmvol_r = int(65536.0 * pow(10.0, db_r / 40.0));
1782 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
1783 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
1786 // ---------------------------------------------------------------------------
1788 // in: buffer
\8d\87\90¬
\90æ
1789 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
1791 void OPNA::Mix(Sample* buffer, int nsamples)
1793 FMMix(buffer, nsamples);
1794 psg.Mix(buffer, nsamples);
1795 ADPCMBMix(buffer, nsamples);
1796 RhythmMix(buffer, nsamples);
1799 // ---------------------------------------------------------------------------
1800 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
1802 #define OPNA_STATE_VERSION 4
1804 void OPNA::SaveState(void *f)
1806 FILEIO *state_fio = (FILEIO *)f;
1808 state_fio->FputUint32_BE(OPNA_STATE_VERSION);
1810 OPNABase::SaveState(f);
1811 for(int i = 0; i < 6; i++) {
1812 state_fio->FputUint8(rhythm[i].pan);
1813 state_fio->FputInt8(rhythm[i].level);
1814 state_fio->FputUint32_BE(rhythm[i].pos);
1816 state_fio->FputInt8(rhythmtl);
1817 state_fio->FputInt32_BE(rhythmtvol_l);
1818 state_fio->FputInt32_BE(rhythmtvol_r);
1819 state_fio->FputUint8(rhythmkey);
1822 bool OPNA::LoadState(void *f)
1824 FILEIO *state_fio = (FILEIO *)f;
1826 if(state_fio->FgetUint32_BE() != OPNA_STATE_VERSION) {
1829 if(!OPNABase::LoadState(f)) {
1832 for(int i = 0; i < 6; i++) {
1833 rhythm[i].pan = state_fio->FgetUint8();
1834 rhythm[i].level = state_fio->FgetInt8();
1835 rhythm[i].pos = state_fio->FgetUint32_BE();
1837 rhythmtl = state_fio->FgetInt8();
1838 rhythmtvol_l = state_fio->FgetInt32_BE();
1839 rhythmtvol_r = state_fio->FgetInt32_BE();
1840 rhythmkey = state_fio->FgetUint8();
1844 #endif // BUILD_OPNA
1846 // ---------------------------------------------------------------------------
1848 // ---------------------------------------------------------------------------
1852 // ---------------------------------------------------------------------------
1859 for (int i=0; i<6; i++)
1862 adpcma[i].level = 0;
1863 adpcma[i].volume_l = 0;
1864 adpcma[i].volume_r = 0;
1867 adpcma[i].start = 0;
1869 adpcma[i].adpcmx = 0;
1870 adpcma[i].adpcmd = 0;
1877 adpcmnotice = 0x8000;
1888 // ---------------------------------------------------------------------------
1891 bool OPNB::Init(uint c, uint r, bool ipflag,
1892 uint8 *_adpcma, int _adpcma_size,
1893 uint8 *_adpcmb, int _adpcmb_size)
1896 if (!SetRate(c, r, ipflag))
1898 if (!OPNABase::Init(c, r, ipflag))
1901 adpcmabuf = _adpcma;
1902 adpcmasize = _adpcma_size;
1905 for (i=0; i<=24; i++) // max 16M bytes
1907 if (_adpcmb_size <= (1 << i))
1909 adpcmmask = (1 << i) - 1;
1914 // adpcmmask = _adpcmb_size - 1;
1915 limitaddr = adpcmmask;
1921 SetVolumeADPCMB(0, 0);
1922 SetVolumeADPCMATotal(0, 0);
1924 SetVolumeADPCMA(i, 0, 0);
1929 // ---------------------------------------------------------------------------
1930 //
\83\8a\83Z
\83b
\83g
1940 for (int i=0; i<6; i++)
1943 adpcma[i].level = 0;
1944 adpcma[i].volume_l = 0;
1945 adpcma[i].volume_r = 0;
1948 adpcma[i].start = 0;
1950 adpcma[i].adpcmx = 0;
1951 adpcma[i].adpcmd = 0;
1955 // ---------------------------------------------------------------------------
1956 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
1958 bool OPNB::SetRate(uint c, uint r, bool ipflag)
1960 if (!OPNABase::SetRate(c, r, ipflag))
1963 adpcmastep = int(double(c) / 54 * 8192 / r);
1967 // ---------------------------------------------------------------------------
1968 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
1970 void OPNB::SetReg(uint addr, uint data)
1976 // omitted registers
1978 case 0x2d: case 0x2e: case 0x2f:
1981 // ADPCM A ---------------------------------------------------------------
1982 case 0x100: // DM/KEYON
1983 if (!(data & 0x80)) // KEY ON
1985 adpcmakey |= data & 0x3f;
1986 for (int c=0; c<6; c++)
1990 ResetStatus(0x100 << c);
1991 adpcma[c].pos = adpcma[c].start;
1992 // adpcma[c].step = 0x10000 - adpcma[c].step;
1994 adpcma[c].adpcmx = 0;
1995 adpcma[c].adpcmd = 0;
1996 adpcma[c].nibble = 0;
2007 adpcmatl = ~data & 63;
2010 case 0x108: case 0x109: case 0x10a:
2011 case 0x10b: case 0x10c: case 0x10d:
2012 adpcma[addr & 7].pan = (data >> 6) & 3;
2013 adpcma[addr & 7].level = ~data & 31;
2016 case 0x110: case 0x111: case 0x112: // START ADDRESS (L)
2017 case 0x113: case 0x114: case 0x115:
2018 case 0x118: case 0x119: case 0x11a: // START ADDRESS (H)
2019 case 0x11b: case 0x11c: case 0x11d:
2020 adpcmareg[addr - 0x110] = data;
2021 adpcma[addr & 7].pos = adpcma[addr & 7].start =
2022 (adpcmareg[(addr&7)+8]*256+adpcmareg[addr&7]) << 9;
2025 case 0x120: case 0x121: case 0x122: // END ADDRESS (L)
2026 case 0x123: case 0x124: case 0x125:
2027 case 0x128: case 0x129: case 0x12a: // END ADDRESS (H)
2028 case 0x12b: case 0x12c: case 0x12d:
2029 adpcmareg[addr - 0x110] = data;
2030 adpcma[addr & 7].stop =
2031 (adpcmareg[(addr&7)+24]*256+adpcmareg[(addr&7)+16] + 1) << 9;
2034 // ADPCMB -----------------------------------------------------------------
2036 if ((data & 0x80) && !adpcmplay)
2039 memaddr = startaddr;
2040 adpcmx = 0, adpcmd = 127;
2045 control1 = data & 0x91;
2049 case 0x11: // Control Register 2
2050 control2 = data & 0xc0;
2053 case 0x12: // Start Address L
2054 case 0x13: // Start Address H
2055 adpcmreg[addr - 0x12 + 0] = data;
2056 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 9;
2057 memaddr = startaddr;
2060 case 0x14: // Stop Address L
2061 case 0x15: // Stop Address H
2062 adpcmreg[addr - 0x14 + 2] = data;
2063 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 9;
2064 // LOG1(" stopaddr %.6x", stopaddr);
2067 case 0x19: // delta-N L
2068 case 0x1a: // delta-N H
2069 adpcmreg[addr - 0x19 + 4] = data;
2070 deltan = adpcmreg[5]*256+adpcmreg[4];
2071 deltan = Max(256, deltan);
2072 adpld = deltan * adplbase >> 16;
2075 case 0x1b: // Level Control
2077 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
2078 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
2081 case 0x1c: // Flag Control
2082 stmask = ~((data & 0xbf) << 8);
2088 OPNABase::SetReg(addr, data);
2094 // ---------------------------------------------------------------------------
2095 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
2097 uint OPNB::GetReg(uint addr)
2100 return psg.GetReg(addr);
2105 // ---------------------------------------------------------------------------
2106 //
\8ag
\92£
\83X
\83e
\81[
\83^
\83X
\82ð
\93Ç
\82Ý
\82±
\82Þ
2108 uint OPNB::ReadStatusEx()
2110 return (status & stmask) >> 8;
2113 // ---------------------------------------------------------------------------
2116 int OPNB::jedi_table[(48+1)*16];
2118 void OPNB::InitADPCMATable()
2120 const static int8 table2[] =
2122 1, 3, 5, 7, 9, 11, 13, 15,
2123 -1, -3, -5, -7, -9,-11,-13,-15,
2126 for (int i=0; i<=48; i++)
2128 int s = int(16.0 * pow (1.1, i) * 3);
2129 for (int j=0; j<16; j++)
2131 jedi_table[i*16+j] = s * table2[j] / 8;
2136 // ---------------------------------------------------------------------------
2137 // ADPCMA
\8d\87\90¬
2139 void OPNB::ADPCMAMix(Sample* buffer, uint count)
2141 const static int decode_tableA1[16] =
2143 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
2144 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
2147 if ((adpcmatvol_l < 128 || adpcmatvol_r < 128) && (adpcmakey & 0x3f))
2149 Sample* limit = buffer + count * 2;
2150 for (int i=0; i<6; i++)
2152 ADPCMA& r = adpcma[i];
2153 if ((adpcmakey & (1 << i)) && r.level < 128)
2155 uint mask_l = r.pan & 2 ? -1 : 0;
2156 uint mask_r = r.pan & 1 ? -1 : 0;
2157 if (rhythmmask_ & (1 << i))
2159 mask_l = mask_r = 0;
2162 int db_l = Limit(adpcmatl+adpcmatvol_l+r.level+r.volume_l, 127, -31);
2163 int db_r = Limit(adpcmatl+adpcmatvol_r+r.level+r.volume_r, 127, -31);
2164 int vol_l = tltable[FM_TLPOS+(db_l << (FM_TLBITS-7))] >> 4;
2165 int vol_r = tltable[FM_TLPOS+(db_r << (FM_TLBITS-7))] >> 4;
2167 Sample* dest = buffer;
2168 for ( ; dest<limit; dest+=2)
2170 r.step += adpcmastep;
2171 if (r.pos >= r.stop)
2173 SetStatus(0x100 << i);
2174 adpcmakey &= ~(1<<i);
2178 for (; r.step > 0x10000; r.step -= 0x10000)
2183 r.nibble = adpcmabuf[r.pos>>1];
2184 data = r.nibble >> 4;
2188 data = r.nibble & 0x0f;
2192 r.adpcmx += jedi_table[r.adpcmd + data];
2193 r.adpcmx = Limit(r.adpcmx, 2048*3-1, -2048*3);
2194 r.adpcmd += decode_tableA1[data];
2195 r.adpcmd = Limit(r.adpcmd, 48*16, 0);
2197 int sample_l = (r.adpcmx * vol_l) >> 10;
2198 int sample_r = (r.adpcmx * vol_r) >> 10;
2199 StoreSample(dest[0], sample_l & mask_l);
2200 StoreSample(dest[1], sample_r & mask_r);
2207 // ---------------------------------------------------------------------------
2210 void OPNB::SetVolumeADPCMATotal(int db_l, int db_r)
2212 db_l = Min(db_l, 20);
2213 db_r = Min(db_r, 20);
2215 adpcmatvol_l = -(db_l * 2 / 3);
2216 adpcmatvol_r = -(db_r * 2 / 3);
2219 void OPNB::SetVolumeADPCMA(int index, int db_l, int db_r)
2221 db_l = Min(db_l, 20);
2222 db_r = Min(db_r, 20);
2224 adpcma[index].volume_l = -(db_l * 2 / 3);
2225 adpcma[index].volume_r = -(db_r * 2 / 3);
2228 void OPNB::SetVolumeADPCMB(int db_l, int db_r)
2230 db_l = Min(db_l, 20);
2231 db_r = Min(db_r, 20);
2234 adpcmvol_l = int(65536.0 * pow(10.0, db_l / 40.0));
2238 adpcmvol_r = int(65536.0 * pow(10.0, db_r / 40.0));
2243 // ---------------------------------------------------------------------------
2245 // in: buffer
\8d\87\90¬
\90æ
2246 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
2248 void OPNB::Mix(Sample* buffer, int nsamples)
2250 FMMix(buffer, nsamples);
2251 psg.Mix(buffer, nsamples);
2252 ADPCMBMix(buffer, nsamples);
2253 ADPCMAMix(buffer, nsamples);
2256 #endif // BUILD_OPNB