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 "../../common.h"
13 #include "../../fileio.h"
15 #include "../../statesub.h"
25 // OPN ch3
\82ª
\8fí
\82ÉPrepare
\82Ì
\91Î
\8fÛ
\82Æ
\82È
\82Á
\82Ä
\82µ
\82Ü
\82¤
\8fá
\8aQ
28 // ---------------------------------------------------------------------------
29 // OPNA: ADPCM
\83f
\81[
\83^
\82Ì
\8ai
\94[
\95û
\8e®
\82Ì
\88á
\82¢ (8bit/1bit)
\82ð
\83G
\83~
\83\85\83\8c\81[
\83g
\82µ
\82È
\82¢
30 //
\82±
\82Ì
\83I
\83v
\83V
\83\87\83\93\82ð
\97L
\8cø
\82É
\82·
\82é
\82Æ ADPCM
\83\81\83\82\83\8a\82Ö
\82Ì
\83A
\83N
\83Z
\83X(
\93Á
\82É 8bit
\83\82\81[
\83h)
\82ª
31 //
\91½
\8f
\8cy
\82
\82È
\82é
\82©
\82à
33 //#define NO_BITTYPE_EMULATION
42 // ---------------------------------------------------------------------------
45 #if defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB) || defined(BUILD_OPN2)
47 uint32 OPNBase::lfotable[8]; // OPNA/B
\97p
57 //
\83p
\83\89\83\81\81[
\83^
\83Z
\83b
\83g
58 void OPNBase::SetParameter(Channel4* ch, uint addr, uint data)
60 const static uint slottable[4] = { 0, 2, 1, 3 };
61 const static uint8 sltable[16] =
63 0, 4, 8, 12, 16, 20, 24, 28,
64 32, 36, 40, 44, 48, 52, 56, 124,
69 uint slot = slottable[(addr >> 2) & 3];
70 Operator* op = &ch->op[slot];
72 switch ((addr >> 4) & 15)
74 case 3: // 30-3E DT/MULTI
75 op->SetDT((data >> 4) & 0x07);
76 op->SetMULTI(data & 0x0f);
80 op->SetTL(data & 0x7f, ((regtc & 0xc0) == 0x80) && (csmch == ch));
83 case 5: // 50-5E KS/AR
84 op->SetKS((data >> 6) & 3);
85 op->SetAR((data & 0x1f) * 2);
88 case 6: // 60-6E DR/AMON
89 op->SetDR((data & 0x1f) * 2);
90 op->SetAMON((data & 0x80) != 0);
94 op->SetSR((data & 0x1f) * 2);
97 case 8: // 80-8E SL/RR
98 op->SetSL(sltable[(data >> 4) & 15]);
99 op->SetRR((data & 0x0f) * 4 + 2);
102 case 9: // 90-9E SSG-EC
103 op->SetSSGEC(data & 0x0f);
109 //
\83\8a\83Z
\83b
\83g
110 void OPNBase::Reset()
119 //
\8a\84\82è
\8d\9e\82Ý
\90M
\8d\86\82Ì
\8eæ
\93¾
120 bool OPNBase::ReadIRQ()
125 //
\83v
\83\8a\83X
\83P
\81[
\83\89\90Ý
\92è
126 void OPNBase::SetPrescaler(uint p)
128 static const char table[3][2] = { { 6, 4 }, { 3, 2 }, { 2, 1 } };
129 static const uint8 table2[8] = { 108, 77, 71, 67, 62, 44, 8, 5 };
134 assert(0 <= prescale && prescale < 3);
136 uint fmclock = clock / table[p][0] / 12;
140 //
\8d\87\90¬
\8eü
\94g
\90\94\82Æ
\8fo
\97Í
\8eü
\94g
\90\94\82Ì
\94ä
141 assert(fmclock < (0x80000000 >> FM_RATIOBITS));
142 uint ratio = ((fmclock << FM_RATIOBITS) + rate/2) / rate;
144 SetTimerPrescaler(table[p][0] * 12);
145 // MakeTimeTable(ratio);
146 chip.SetRatio(ratio);
147 psg.SetClock(clock / table[p][1], psgrate);
149 for (int i=0; i<8; i++)
151 lfotable[i] = (ratio << (2+FM_LFOCBITS-FM_RATIOBITS)) / table2[i];
157 bool OPNBase::Init(uint c, uint r)
166 void OPNBase::SetVolumeFM(int db_l, int db_r)
168 db_l = Min(db_l, 20);
169 db_r = Min(db_r, 20);
172 fmvolume_l = int(16384.0 * pow(10.0, db_l / 40.0));
176 fmvolume_r = int(16384.0 * pow(10.0, db_r / 40.0));
181 //
\83^
\83C
\83}
\81[
\8e\9e\8aÔ
\8f\88\97\9d
182 void OPNBase::TimerA()
184 if ((regtc & 0xc0) == 0x80)
186 csmch->KeyControl(0x00);
187 csmch->KeyControl(0x0f);
191 //
\8a\84\82è
\8d\9e\82Ý
\90M
\8d\86\82Ì
\90Ý
\92è
192 void OPNBase::Intr(bool value)
197 // ---------------------------------------------------------------------------
198 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
200 #define OPN_BASE_STATE_VERSION 2
202 bool OPNBase::ProcessState(void *f, bool loading)
204 FILEIO *state_fio = (FILEIO *)f;
206 if(!state_fio->StateCheckUint32(OPN_BASE_STATE_VERSION)) {
210 if(!Timer::ProcessState(f, loading)) {
213 state_fio->StateInt32(fmvolume_l);
214 state_fio->StateInt32(fmvolume_r);
215 state_fio->StateUint32(clock);
216 state_fio->StateUint32(rate);
217 state_fio->StateUint32(psgrate);
218 state_fio->StateUint32(status);
219 state_fio->StateBool(interrupt);
220 state_fio->StateUint8(prescale);
222 // Make force-restore around prescaler and timers. 20180625 K.O
227 if(!chip.ProcessState(f, loading)) {
230 if(!psg.ProcessState(f, loading)) {
236 #endif // defined(BUILD_OPN) || defined(BUILD_OPNA) || defined (BUILD_OPNB) || defined(BUILD_OPN2)
238 // ---------------------------------------------------------------------------
250 for (int i=0; i<3; i++)
252 ch[i].SetChip(&chip);
253 ch[i].SetType(typeN);
258 bool OPN::Init(uint c, uint r, bool ip, const char*)
260 if (!SetRate(c, r, ip))
271 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
272 bool OPN::SetRate(uint c, uint r, bool)
280 //
\83\8a\83Z
\83b
\83g
284 for (i=0x20; i<0x28; i++) SetReg(i, 0);
285 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
293 //
\83\8c\83W
\83X
\83^
\93Ç
\82Ý
\8d\9e\82Ý
294 uint OPN::GetReg(uint addr)
297 return psg.GetReg(addr);
303 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
304 void OPN::SetReg(uint addr, uint data)
306 // LOG2("reg[%.2x] <- %.2x\n", addr, data);
313 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
314 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
315 psg.SetReg(addr, data);
318 case 0x24: case 0x25:
319 SetTimerA(addr, data);
327 SetTimerControl(data);
330 case 0x28: // Key On/Off
332 ch[data & 3].KeyControl(data >> 4);
335 case 0x2d: case 0x2e: case 0x2f:
336 SetPrescaler(addr-0x2d);
340 case 0xa0: case 0xa1: case 0xa2:
341 fnum[c] = data + fnum2[c] * 0x100;
344 case 0xa4: case 0xa5: case 0xa6:
345 fnum2[c] = uint8(data);
348 case 0xa8: case 0xa9: case 0xaa:
349 fnum3[c] = data + fnum2[c+3] * 0x100;
352 case 0xac: case 0xad: case 0xae:
353 fnum2[c+3] = uint8(data);
356 case 0xb0: case 0xb1: case 0xb2:
357 ch[c].SetFB((data >> 3) & 7);
358 ch[c].SetAlgorithm(data & 7);
364 if ((addr & 0xf0) == 0x60)
366 OPNBase::SetParameter(&ch[c], addr, data);
372 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
373 void OPN::SetStatus(uint bits)
375 if (!(status & bits))
382 void OPN::ResetStatus(uint bit)
389 //
\83}
\83X
\83N
\90Ý
\92è
390 void OPN::SetChannelMask(uint mask)
392 for (int i=0; i<3; i++)
393 ch[i].Mute(!!(mask & (1 << i)));
394 psg.SetChannelMask(mask >> 6);
399 void OPN::Mix(Sample* buffer, int nsamples)
401 #define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
402 #define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
404 psg.Mix(buffer, nsamples);
407 ch[0].SetFNum(fnum[0]);
408 ch[1].SetFNum(fnum[1]);
410 ch[2].SetFNum(fnum[2]);
413 ch[2].op[0].SetFNum(fnum3[1]);
414 ch[2].op[1].SetFNum(fnum3[2]);
415 ch[2].op[2].SetFNum(fnum3[0]);
416 ch[2].op[3].SetFNum(fnum[2]);
419 int actch = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
422 Sample* limit = buffer + nsamples * 2;
423 for (Sample* dest = buffer; dest < limit; dest+=2)
427 if (actch & 0x01) s = ch[0].Calc();
428 if (actch & 0x04) s += ch[1].Calc();
429 if (actch & 0x10) s += ch[2].Calc();
430 s_l = IStoSampleL(s);
431 s_r = IStoSampleR(s);
432 StoreSample(dest[0], s_l);
433 StoreSample(dest[1], s_r);
440 // ---------------------------------------------------------------------------
441 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
443 #define OPN_STATE_VERSION 1
445 bool OPN::ProcessState(void *f, bool loading)
447 FILEIO *state_fio = (FILEIO *)f;
449 if(!state_fio->StateCheckUint32(OPN_STATE_VERSION)) {
452 if(!OPNBase::ProcessState(f, loading)) {
456 if(!state_fio->StateCheckUint32(OPN_STATE_VERSION)) {
459 if(!OPNBase::ProcessState(f, loading)) {
463 state_fio->StateBuffer(fnum, sizeof(fnum), 1);
464 state_fio->StateBuffer(fnum3, sizeof(fnum3), 1);
465 state_fio->StateBuffer(fnum2, sizeof(fnum2), 1);
466 for(int i = 0; i < 3; i++) {
467 if(!ch[i].ProcessState(f, loading)) {
476 // ---------------------------------------------------------------------------
477 // YM2608/2610 common part
478 // ---------------------------------------------------------------------------
480 #if defined(BUILD_OPNA) || defined(BUILD_OPNB)
482 int OPNABase::amtable[FM_LFOENTS] = { -1, };
483 int OPNABase::pmtable[FM_LFOENTS];
485 int32 OPNABase::tltable[FM_TLENTS+FM_TLPOS];
486 bool OPNABase::tablehasmade = false;
501 for (int i=0; i<6; i++)
503 ch[i].SetChip(&chip);
504 ch[i].SetType(typeN);
508 OPNABase::~OPNABase()
512 // ---------------------------------------------------------------------------
515 bool OPNABase::Init(uint c, uint r, bool)
527 // ---------------------------------------------------------------------------
528 //
\83e
\81[
\83u
\83\8b\8dì
\90¬
530 void OPNABase::MakeTable2()
534 for (int i=-FM_TLPOS; i<FM_TLENTS; i++)
536 tltable[i+FM_TLPOS] = uint(65536. * pow(2.0, i * -16. / FM_TLENTS))-1;
543 // ---------------------------------------------------------------------------
544 //
\83\8a\83Z
\83b
\83g
546 void OPNABase::Reset()
551 for (i=0x20; i<0x28; i++) SetReg(i, 0);
552 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
553 for (i=0x130; i<0x1c0; i++) SetReg(i, 0);
554 for (i=0x100; i<0x110; i++) SetReg(i, 0);
555 for (i=0x10; i<0x20; i++) SetReg(i, 0);
569 apout0_l = apout1_l = adpcmout_l = 0;
570 apout0_r = apout1_r = adpcmout_r = 0;
579 // ---------------------------------------------------------------------------
580 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
582 bool OPNABase::SetRate(uint c, uint r, bool)
584 c /= 2; //
\8f]
\97\88\94Å
\82Æ
\82Ì
\8cÝ
\8a·
\90«
\82ð
\8fd
\8e\8b\82µ
\82½
\82¯
\82è
\82á
\83R
\83\81\83\93\83g
\83A
\83E
\83g
\82µ
\82æ
\82¤
588 adplbase = int(8192. * (clock/72.) / r);
589 adpld = deltan * adplbase >> 16;
593 lfodcount = reg22 & 0x08 ? lfotable[reg22 & 7] : 0;
598 // ---------------------------------------------------------------------------
599 //
\83`
\83\83\83\93\83l
\83\8b\83}
\83X
\83N
\82Ì
\90Ý
\92è
601 void OPNABase::SetChannelMask(uint mask)
603 for (int i=0; i<6; i++)
604 ch[i].Mute(!!(mask & (1 << i)));
605 psg.SetChannelMask(mask >> 6);
606 adpcmmask_ = (mask & (1 << 9)) != 0;
607 rhythmmask_ = (mask >> 10) & ((1 << 6) - 1);
610 // ---------------------------------------------------------------------------
611 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
613 void OPNABase::SetReg(uint addr, uint data)
620 // Timer -----------------------------------------------------------------
621 case 0x24: case 0x25:
622 SetTimerA(addr, data);
630 SetTimerControl(data);
633 // Misc ------------------------------------------------------------------
634 case 0x28: // Key On/Off
637 c = (data & 3) + (data & 4 ? 3 : 0);
638 ch[c].KeyControl(data >> 4);
642 // Status Mask -----------------------------------------------------------
645 // UpdateStatus(); //?
648 // Prescaler -------------------------------------------------------------
649 case 0x2d: case 0x2e: case 0x2f:
650 SetPrescaler(addr-0x2d);
653 // F-Number --------------------------------------------------------------
654 case 0x1a0: case 0x1a1: case 0x1a2:
656 case 0xa0: case 0xa1: case 0xa2:
657 fnum[c] = data + fnum2[c] * 0x100;
658 ch[c].SetFNum(fnum[c]);
661 case 0x1a4: case 0x1a5: case 0x1a6:
663 case 0xa4 : case 0xa5: case 0xa6:
664 fnum2[c] = uint8(data);
667 case 0xa8: case 0xa9: case 0xaa:
668 fnum3[c] = data + fnum2[c+6] * 0x100;
671 case 0xac : case 0xad: case 0xae:
672 fnum2[c+6] = uint8(data);
675 // Algorithm -------------------------------------------------------------
677 case 0x1b0: case 0x1b1: case 0x1b2:
679 case 0xb0: case 0xb1: case 0xb2:
680 ch[c].SetFB((data >> 3) & 7);
681 ch[c].SetAlgorithm(data & 7);
684 case 0x1b4: case 0x1b5: case 0x1b6:
686 case 0xb4: case 0xb5: case 0xb6:
687 pan[c] = (data >> 6) & 3;
691 // LFO -------------------------------------------------------------------
693 modified = reg22 ^ data;
697 lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0;
700 // PSG -------------------------------------------------------------------
701 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
702 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
703 psg.SetReg(addr, data);
706 //
\89¹
\90F ------------------------------------------------------------------
712 OPNBase::SetParameter(&ch[c], addr, data);
718 // ---------------------------------------------------------------------------
721 void OPNABase::SetADPCMBReg(uint addr, uint data)
725 case 0x00: // Control Register 1
726 if ((data & 0x80) && !adpcmplay)
730 adpcmx = 0, adpcmd = 127;
740 case 0x01: // Control Register 2
742 granuality = control2 & 2 ? 1 : 4;
745 case 0x02: // Start Address L
746 case 0x03: // Start Address H
747 adpcmreg[addr - 0x02 + 0] = data;
748 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 6;
750 // LOG1(" startaddr %.6x", startaddr);
753 case 0x04: // Stop Address L
754 case 0x05: // Stop Address H
755 adpcmreg[addr - 0x04 + 2] = data;
756 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 6;
757 // LOG1(" stopaddr %.6x", stopaddr);
760 case 0x08: // ADPCM data
761 if ((control1 & 0x60) == 0x60)
763 // LOG2(" Wr [0x%.5x] = %.2x", memaddr, data);
768 case 0x09: // delta-N L
769 case 0x0a: // delta-N H
770 adpcmreg[addr - 0x09 + 4] = data;
771 deltan = adpcmreg[5]*256+adpcmreg[4];
772 deltan = Max(256, deltan);
773 adpld = deltan * adplbase >> 16;
776 case 0x0b: // Level Control
778 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
779 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
782 case 0x0c: // Limit Address L
783 case 0x0d: // Limit Address H
784 adpcmreg[addr - 0x0c + 6] = data;
785 limitaddr = (adpcmreg[7]*256+adpcmreg[6] + 1) << 6;
786 // LOG1(" limitaddr %.6x", limitaddr);
789 case 0x10: // Flag Control
792 // for Firecracker Music collection (Hi-speed PCM loader)
798 stmask = ~(data & 0x1f);
799 // UpdateStatus(); //???
806 // ---------------------------------------------------------------------------
807 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
809 uint OPNA::GetReg(uint addr)
812 return psg.GetReg(addr);
816 // LOG1("%d:reg[108] -> ", Diag::GetCPUTick());
818 uint data = adpcmreadbuf & 0xff;
820 if ((control1 & 0x60) == 0x20)
822 adpcmreadbuf |= ReadRAM() << 8;
823 // LOG2("Rd [0x%.6x:%.2x] ", memaddr, adpcmreadbuf >> 8);
838 // ---------------------------------------------------------------------------
839 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
841 void OPNABase::SetStatus(uint bits)
843 if (!(status & bits))
845 // LOG2("SetStatus(%.2x %.2x)\n", bits, stmask);
846 status |= bits & stmask;
850 // LOG1("SetStatus(%.2x) - ignored\n", bits);
853 void OPNABase::ResetStatus(uint bits)
856 // LOG1("ResetStatus(%.2x)\n", bits);
860 inline void OPNABase::UpdateStatus()
862 // LOG2("%d:INT = %d\n", Diag::GetCPUTick(), (status & stmask & reg29) != 0);
863 Intr((status & stmask & reg29) != 0);
866 // ---------------------------------------------------------------------------
867 // ADPCM RAM
\82Ö
\82Ì
\8f\91\8d\9e\82Ý
\91\80\8dì
869 void OPNABase::WriteRAM(uint data)
871 #ifndef NO_BITTYPE_EMULATION
875 adpcmbuf[(memaddr >> 4) & 0x3ffff] = data;
881 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
882 uint bank = (memaddr >> 1) & 7;
883 uint8 mask = 1 << bank;
886 p[0x00000] = (p[0x00000] & ~mask) | (uint8(data) & mask); data >>= 1;
887 p[0x08000] = (p[0x08000] & ~mask) | (uint8(data) & mask); data >>= 1;
888 p[0x10000] = (p[0x10000] & ~mask) | (uint8(data) & mask); data >>= 1;
889 p[0x18000] = (p[0x18000] & ~mask) | (uint8(data) & mask); data >>= 1;
890 p[0x20000] = (p[0x20000] & ~mask) | (uint8(data) & mask); data >>= 1;
891 p[0x28000] = (p[0x28000] & ~mask) | (uint8(data) & mask); data >>= 1;
892 p[0x30000] = (p[0x30000] & ~mask) | (uint8(data) & mask); data >>= 1;
893 p[0x38000] = (p[0x38000] & ~mask) | (uint8(data) & mask);
897 adpcmbuf[(memaddr >> granuality) & 0x3ffff] = data;
898 memaddr += 1 << granuality;
901 if (memaddr == stopaddr)
904 statusnext = 0x04; // EOS
907 if (memaddr == limitaddr)
909 // LOG1("Limit ! (%.8x)\n", limitaddr);
915 // ---------------------------------------------------------------------------
916 // ADPCM RAM
\82©
\82ç
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
\91\80\8dì
918 uint OPNABase::ReadRAM()
921 #ifndef NO_BITTYPE_EMULATION
925 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
931 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff];
932 uint bank = (memaddr >> 1) & 7;
933 uint8 mask = 1 << bank;
935 data = (p[0x38000] & mask);
936 data = data * 2 + (p[0x30000] & mask);
937 data = data * 2 + (p[0x28000] & mask);
938 data = data * 2 + (p[0x20000] & mask);
939 data = data * 2 + (p[0x18000] & mask);
940 data = data * 2 + (p[0x10000] & mask);
941 data = data * 2 + (p[0x08000] & mask);
942 data = data * 2 + (p[0x00000] & mask);
947 data = adpcmbuf[(memaddr >> granuality) & 0x3ffff];
948 memaddr += 1 << granuality;
950 if (memaddr == stopaddr)
953 statusnext = 0x04; // EOS
956 if (memaddr == limitaddr)
958 // LOG1("Limit ! (%.8x)\n", limitaddr);
961 if (memaddr < stopaddr)
967 inline int OPNABase::DecodeADPCMBSample(uint data)
969 static const int table1[16] =
971 1, 3, 5, 7, 9, 11, 13, 15,
972 -1, -3, -5, -7, -9, -11, -13, -15,
974 static const int table2[16] =
976 57, 57, 57, 57, 77, 102, 128, 153,
977 57, 57, 57, 57, 77, 102, 128, 153,
979 adpcmx = Limit(adpcmx + table1[data] * adpcmd / 8, 32767, -32768);
980 adpcmd = Limit(adpcmd * table2[data] / 64, 24576, 127);
985 // ---------------------------------------------------------------------------
986 // ADPCM RAM
\82©
\82ç
\82Ì nibble
\93Ç
\82Ý
\8d\9e\82Ý
\8by
\82Ñ ADPCM
\93W
\8aJ
988 int OPNABase::ReadRAMN()
993 #ifndef NO_BITTYPE_EMULATION
996 data = adpcmbuf[(memaddr >> 4) & 0x3ffff];
999 return DecodeADPCMBSample(data >> 4);
1004 uint8* p = &adpcmbuf[(memaddr >> 4) & 0x7fff] + ((~memaddr & 1) << 17);
1005 uint bank = (memaddr >> 1) & 7;
1006 uint8 mask = 1 << bank;
1008 data = (p[0x18000] & mask);
1009 data = data * 2 + (p[0x10000] & mask);
1010 data = data * 2 + (p[0x08000] & mask);
1011 data = data * 2 + (p[0x00000] & mask);
1015 return DecodeADPCMBSample(data);
1018 data = adpcmbuf[(memaddr >> granuality) & adpcmmask];
1019 memaddr += 1 << (granuality-1);
1020 if (memaddr & (1 << (granuality-1)))
1021 return DecodeADPCMBSample(data >> 4);
1027 data = adpcmbuf[(memaddr >> 1) & adpcmmask];
1030 return DecodeADPCMBSample(data >> 4);
1034 DecodeADPCMBSample(data);
1037 if (memaddr == stopaddr)
1039 if (control1 & 0x10)
1041 memaddr = startaddr;
1043 adpcmx = 0, adpcmd = 127;
1044 // for PC-8801FA/MA shop demonstration
1045 SetStatus(adpcmnotice);
1050 memaddr &= adpcmmask; //0x3fffff;
1051 SetStatus(adpcmnotice);
1056 if (memaddr == limitaddr)
1062 // ---------------------------------------------------------------------------
1063 //
\8ag
\92£
\83X
\83e
\81[
\83^
\83X
\82ð
\93Ç
\82Ý
\82±
\82Þ
1065 uint OPNABase::ReadStatusEx()
1067 uint r = ((status | 8) & stmask) | (adpcmplay ? 0x20 : 0);
1068 status |= statusnext;
1073 // ---------------------------------------------------------------------------
1076 inline void OPNABase::DecodeADPCMB()
1078 apout0_l = apout1_l;
1079 apout0_r = apout1_r;
1080 int ram = ReadRAMN();
1081 int s_l = (ram * adpcmvolume_l) >> 13;
1082 int s_r = (ram * adpcmvolume_r) >> 13;
1083 apout1_l = adpcmout_l + s_l;
1084 apout1_r = adpcmout_r + s_r;
1089 // ---------------------------------------------------------------------------
1092 void OPNABase::ADPCMBMix(Sample* dest, uint count)
1094 uint mask_l = control2 & 0x80 ? -1 : 0;
1095 uint mask_r = control2 & 0x40 ? -1 : 0;
1098 mask_l = mask_r = 0;
1103 // LOG2("ADPCM Play: %d DeltaN: %d\n", adpld, deltan);
1104 if (adpld <= 8192) // fplay < fsamp
1106 for (; count>0; count--)
1115 int s_l = (adplc * apout0_l + (8192-adplc) * apout1_l) >> 13;
1116 int s_r = (adplc * apout0_r + (8192-adplc) * apout1_r) >> 13;
1117 StoreSample(dest[0], s_l & mask_l);
1118 StoreSample(dest[1], s_r & mask_r);
1122 for (; count>0 && (apout0_l || apout0_r); count--)
1126 apout0_l = apout1_l, apout1_l = 0;
1127 apout0_r = apout1_r, apout1_r = 0;
1130 int s_l = (adplc * apout1_l) >> 13;
1131 int s_r = (adplc * apout1_r) >> 13;
1132 StoreSample(dest[0], s_l & mask_l);
1133 StoreSample(dest[1], s_r & mask_r);
1138 else // fplay > fsamp (adpld = fplay/famp*8192)
1140 int t = (-8192*8192)/adpld;
1141 for (; count>0; count--)
1143 int s_l = apout0_l * (8192+adplc);
1144 int s_r = apout0_r * (8192+adplc);
1150 s_l -= apout0_l * Max(adplc, t);
1151 s_r -= apout0_r * Max(adplc, t);
1157 StoreSample(dest[0], s_l & mask_l);
1158 StoreSample(dest[1], s_r & mask_r);
1167 apout0_l = apout1_l = adpcmout_l = 0;
1168 apout0_r = apout1_r = adpcmout_r = 0;
1173 // ---------------------------------------------------------------------------
1175 // in: buffer
\8d\87\90¬
\90æ
1176 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
1178 void OPNABase::FMMix(Sample* buffer, int nsamples)
1180 if (fmvolume_l > 0 || fmvolume_r > 0)
1184 if (!(regtc & 0xc0))
1185 csmch->SetFNum(fnum[csmch-ch]);
1188 //
\8cø
\89Ê
\89¹
\83\82\81[
\83h
1189 csmch->op[0].SetFNum(fnum3[1]); csmch->op[1].SetFNum(fnum3[2]);
1190 csmch->op[2].SetFNum(fnum3[0]); csmch->op[3].SetFNum(fnum[2]);
1193 int act = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
1195 act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6;
1196 if (!(reg22 & 0x08))
1201 Mix6(buffer, nsamples, act);
1206 // ---------------------------------------------------------------------------
1208 void OPNABase::MixSubSL(int activech, ISample** dest)
1210 if (activech & 0x001) (*dest[0] = ch[0].CalcL());
1211 if (activech & 0x004) (*dest[1] += ch[1].CalcL());
1212 if (activech & 0x010) (*dest[2] += ch[2].CalcL());
1213 if (activech & 0x040) (*dest[3] += ch[3].CalcL());
1214 if (activech & 0x100) (*dest[4] += ch[4].CalcL());
1215 if (activech & 0x400) (*dest[5] += ch[5].CalcL());
1218 inline void OPNABase::MixSubS(int activech, ISample** dest)
1220 if (activech & 0x001) (*dest[0] = ch[0].Calc());
1221 if (activech & 0x004) (*dest[1] += ch[1].Calc());
1222 if (activech & 0x010) (*dest[2] += ch[2].Calc());
1223 if (activech & 0x040) (*dest[3] += ch[3].Calc());
1224 if (activech & 0x100) (*dest[4] += ch[4].Calc());
1225 if (activech & 0x400) (*dest[5] += ch[5].Calc());
1228 // ---------------------------------------------------------------------------
1230 void OPNABase::BuildLFOTable()
1232 if (amtable[0] == -1)
1234 for (int c=0; c<256; c++)
1237 if (c < 0x40) v = c * 2 + 0x80;
1238 else if (c < 0xc0) v = 0x7f - (c - 0x40) * 2 + 0x80;
1239 else v = (c - 0xc0) * 2;
1242 if (c < 0x80) v = 0xff - c * 2;
1243 else v = (c - 0x80) * 2;
1244 amtable[c] = v & ~3;
1249 // ---------------------------------------------------------------------------
1251 inline void OPNABase::LFO()
1253 // LOG3("%4d - %8d, %8d\n", c, lfocount, lfodcount);
1255 // Operator::SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1256 // Operator::SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1257 chip.SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1258 chip.SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
1259 lfocount += lfodcount;
1262 // ---------------------------------------------------------------------------
1265 #define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
1266 #define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
1268 void OPNABase::Mix6(Sample* buffer, int nsamples, int activech)
1273 idest[0] = &ibuf[pan[0]];
1274 idest[1] = &ibuf[pan[1]];
1275 idest[2] = &ibuf[pan[2]];
1276 idest[3] = &ibuf[pan[3]];
1277 idest[4] = &ibuf[pan[4]];
1278 idest[5] = &ibuf[pan[5]];
1280 Sample* limit = buffer + nsamples * 2;
1281 for (Sample* dest = buffer; dest < limit; dest+=2)
1283 ibuf[1] = ibuf[2] = ibuf[3] = 0;
1284 if (activech & 0xaaa)
1285 LFO(), MixSubSL(activech, idest);
1287 MixSubS(activech, idest);
1288 StoreSample(dest[0], IStoSampleL(ibuf[2] + ibuf[3]));
1289 StoreSample(dest[1], IStoSampleR(ibuf[1] + ibuf[3]));
1293 // ---------------------------------------------------------------------------
1294 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
1296 #define OPNA_BASE_STATE_VERSION 2
1298 bool OPNABase::ProcessState(void *f, bool loading)
1300 FILEIO *state_fio = (FILEIO *)f;
1302 if(!state_fio->StateCheckUint32(OPNA_BASE_STATE_VERSION)) {
1305 if(!OPNBase::ProcessState(f, loading)) {
1308 state_fio->StateBuffer(pan, sizeof(pan), 1);
1309 state_fio->StateBuffer(fnum2, sizeof(fnum2), 1);
1310 state_fio->StateUint8(reg22);
1311 state_fio->StateUint32(reg29);
1312 state_fio->StateUint32(stmask);
1313 state_fio->StateUint32(statusnext);
1314 state_fio->StateUint32(lfocount);
1315 state_fio->StateUint32(lfodcount);
1316 state_fio->StateBuffer(fnum, sizeof(fnum), 1);
1317 state_fio->StateBuffer(fnum3, sizeof(fnum3), 1);
1318 state_fio->StateBuffer(adpcmbuf, 0x40000, 1);
1319 state_fio->StateUint32(adpcmmask);
1320 state_fio->StateUint32(adpcmnotice);
1321 state_fio->StateUint32(startaddr);
1322 state_fio->StateUint32(stopaddr);
1323 state_fio->StateUint32(memaddr);
1324 state_fio->StateUint32(limitaddr);
1325 state_fio->StateInt32(adpcmlevel);
1326 state_fio->StateInt32(adpcmvolume_l);
1327 state_fio->StateInt32(adpcmvolume_r);
1328 state_fio->StateInt32(adpcmvol_l);
1329 state_fio->StateInt32(adpcmvol_r);
1330 state_fio->StateUint32(deltan);
1331 state_fio->StateInt32(adplc);
1332 state_fio->StateInt32(adpld);
1333 state_fio->StateUint32(adplbase);
1334 state_fio->StateInt32(adpcmx);
1335 state_fio->StateInt32(adpcmd);
1336 state_fio->StateInt32(adpcmout_l);
1337 state_fio->StateInt32(adpcmout_r);
1338 state_fio->StateInt32(apout0_l);
1339 state_fio->StateInt32(apout0_r);
1340 state_fio->StateInt32(apout1_l);
1341 state_fio->StateInt32(apout1_r);
1342 state_fio->StateUint32(adpcmreadbuf);
1343 state_fio->StateBool(adpcmplay);
1344 state_fio->StateInt8(granuality);
1345 state_fio->StateBool(adpcmmask_);
1346 state_fio->StateUint8(control1);
1347 state_fio->StateUint8(control2);
1348 state_fio->StateBuffer(adpcmreg, sizeof(adpcmreg), 1);
1349 state_fio->StateInt32(rhythmmask_);
1350 for(int i = 0; i < 6; i++) {
1351 if(!ch[i].ProcessState(f, loading)) {
1360 #endif // defined(BUILD_OPNA) || defined(BUILD_OPNB)
1362 // ---------------------------------------------------------------------------
1364 // ---------------------------------------------------------------------------
1368 // ---------------------------------------------------------------------------
1373 for (int i=0; i<6; i++)
1375 rhythm[i].sample = 0;
1378 rhythm[i].volume_l = 0;
1379 rhythm[i].volume_r = 0;
1380 rhythm[i].level = 0;
1385 adpcmmask = 0x3ffff;
1390 // ---------------------------------------------------------------------------
1395 for (int i=0; i<6; i++)
1396 delete[] rhythm[i].sample;
1401 // ---------------------------------------------------------------------------
1404 bool OPNA::Init(uint c, uint r, bool ipflag, const _TCHAR* path)
1407 LoadRhythmSample(path);
1410 adpcmbuf = new uint8[0x40000];
1414 if (!SetRate(c, r, ipflag))
1416 if (!OPNABase::Init(c, r, ipflag))
1421 SetVolumeADPCM(0, 0);
1422 SetVolumeRhythmTotal(0, 0);
1423 for (int i=0; i<6; i++)
1424 SetVolumeRhythm(i, 0, 0);
1428 // ---------------------------------------------------------------------------
1429 //
\83\8a\83Z
\83b
\83g
1436 limitaddr = 0x3ffff;
1440 // ---------------------------------------------------------------------------
1441 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
1443 bool OPNA::SetRate(uint c, uint r, bool ipflag)
1445 if (!OPNABase::SetRate(c, r, ipflag))
1448 for (int i=0; i<6; i++)
1450 rhythm[i].step = rhythm[i].rate * 1024 / r;
1456 // ---------------------------------------------------------------------------
1457 //
\83\8a\83Y
\83\80\89¹
\82ð
\93Ç
\82Ý
\82±
\82Þ
1459 bool OPNA::LoadRhythmSample(const _TCHAR* path)
1461 static const _TCHAR* rhythmname[6] =
1463 _T("BD"), _T("SD"), _T("TOP"), _T("HH"), _T("TOM"), _T("RIM"),
1474 _TCHAR buf[_MAX_PATH] = _T("");
1475 memset(buf, 0x00, sizeof(buf));
1477 _tcsncpy(buf, path, _MAX_PATH - 1);
1478 _tcsncat(buf, _T("2608_"), _MAX_PATH - 1);
1479 _tcsncat(buf, rhythmname[i], _MAX_PATH- 1);
1480 _tcsncat(buf, _T(".WAV"), _MAX_PATH - 1);
1482 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1486 memset(buf, 0x00, sizeof(buf));
1488 _tcsncpy(buf, path, _MAX_PATH - 1);
1490 _tcsncat(buf, _T("2608_RYM.WAV"), _MAX_PATH - 1);
1491 if (!file.Fopen(buf, FILEIO_READ_BINARY))
1498 file.Fread(&whdr, sizeof(whdr), 1);
1500 uint8 subchunkname[4];
1501 bool is_eof = false;
1502 file.Fseek(EndianFromLittle_DWORD(whdr.fmt_chunk.size) - 16, FILEIO_SEEK_CUR);
1505 if(file.Fread(&chunk, sizeof(chunk), 1) != 1) {
1509 if(strncmp(chunk.id, "data", 4) == 0) {
1512 file.Fseek(EndianFromLittle_DWORD(chunk.size), FILEIO_SEEK_CUR);
1516 // rhythm[i].rate = whdr.sample_rate;
1517 // rhythm[i].step = rhythm[i].rate * 1024 / rate;
1518 // rhythm[i].pos = rhythm[i].size = fsize * 1024;
1519 // delete rhythm[i].sample;
1520 // rhythm[i].sample = new int16[fsize];
1521 // memset(rhythm[i].sample, 0x00, fsize * 2);
1525 fsize = EndianFromLittle_DWORD(chunk.size);
1528 if ((fsize >= 0x100000) || (EndianFromLittle_WORD(whdr.format_id) != 1) || (EndianFromLittle_WORD(whdr.channels) != 1))
1530 fsize = Max(fsize, (1<<31)/1024);
1532 delete rhythm[i].sample;
1533 rhythm[i].sample = new int16[fsize];
1534 if (!rhythm[i].sample)
1536 for(int __iptr = 0; __iptr < fsize; __iptr++) {
1543 pair16.b.l = file.FgetUint8();
1544 pair16.b.h = file.FgetUint8();
1545 rhythm[i].sample[__iptr] = pair16.s16;
1547 //file.Fread(rhythm[i].sample, fsize * 2, 1);
1549 rhythm[i].rate = EndianFromLittle_DWORD(whdr.sample_rate);
1550 rhythm[i].step = rhythm[i].rate * 1024 / rate;
1551 rhythm[i].pos = rhythm[i].size = fsize * 1024;
1556 // printf("NG %d\n", i);
1559 delete[] rhythm[i].sample;
1560 rhythm[i].sample = 0;
1570 // ---------------------------------------------------------------------------
1571 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
1573 void OPNA::SetReg(uint addr, uint data)
1581 // UpdateStatus(); //?
1584 // Rhythm ----------------------------------------------------------------
1585 case 0x10: // DM/KEYON
1586 if (!(data & 0x80)) // KEY ON
1588 rhythmkey |= data & 0x3f;
1589 if (data & 0x01) rhythm[0].pos = 0;
1590 if (data & 0x02) rhythm[1].pos = 0;
1591 if (data & 0x04) rhythm[2].pos = 0;
1592 if (data & 0x08) rhythm[3].pos = 0;
1593 if (data & 0x10) rhythm[4].pos = 0;
1594 if (data & 0x20) rhythm[5].pos = 0;
1603 rhythmtl = ~data & 63;
1606 case 0x18: // Bass Drum
1607 case 0x19: // Snare Drum
1608 case 0x1a: // Top Cymbal
1610 case 0x1c: // Tom-tom
1611 case 0x1d: // Rim shot
1612 rhythm[addr & 7].pan = (data >> 6) & 3;
1613 rhythm[addr & 7].level = ~data & 31;
1616 case 0x100: case 0x101:
1617 case 0x102: case 0x103:
1618 case 0x104: case 0x105:
1619 case 0x108: case 0x109:
1620 case 0x10a: case 0x10b:
1621 case 0x10c: case 0x10d:
1623 OPNABase::SetADPCMBReg(addr - 0x100, data);
1627 // for PC-8801FA/MA shop demonstration
1628 if ((control1 & 0x10) && (status & adpcmnotice)) {
1629 ResetStatus(adpcmnotice);
1634 OPNABase::SetReg(addr, data);
1640 // ---------------------------------------------------------------------------
1641 //
\83\8a\83Y
\83\80\8d\87\90¬
1643 void OPNA::RhythmMix(Sample* buffer, uint count)
1645 if ((rhythmtvol_l < 128 || rhythmtvol_r < 128) && rhythm[0].sample && (rhythmkey & 0x3f))
1647 Sample* limit = buffer + count * 2;
1648 for (int i=0; i<6; i++)
1650 Rhythm& r = rhythm[i];
1651 if ((rhythmkey & (1 << i)) && r.level < 128)
1653 int db_l = Limit(rhythmtl+rhythmtvol_l+r.level+r.volume_l, 127, -31);
1654 int db_r = Limit(rhythmtl+rhythmtvol_r+r.level+r.volume_r, 127, -31);
1655 int vol_l = tltable[FM_TLPOS+(db_l << (FM_TLBITS-7))] >> 4;
1656 int vol_r = tltable[FM_TLPOS+(db_r << (FM_TLBITS-7))] >> 4;
1657 int mask_l = -((r.pan >> 1) & 1);
1658 int mask_r = -(r.pan & 1);
1660 if (rhythmmask_ & (1 << i))
1662 mask_l = mask_r = 0;
1665 for (Sample* dest = buffer; dest<limit && r.pos < r.size; dest+=2)
1667 int sample_l = (r.sample[r.pos / 1024] * vol_l) >> 12;
1668 int sample_r = (r.sample[r.pos / 1024] * vol_r) >> 12;
1670 StoreSample(dest[0], sample_l & mask_l);
1671 StoreSample(dest[1], sample_r & mask_r);
1678 // ---------------------------------------------------------------------------
1681 void OPNA::SetVolumeRhythmTotal(int db_l, int db_r)
1683 db_l = Min(db_l, 20);
1684 db_r = Min(db_r, 20);
1686 rhythmtvol_l = -(db_l * 2 / 3);
1687 rhythmtvol_r = -(db_r * 2 / 3);
1690 void OPNA::SetVolumeRhythm(int index, int db_l, int db_r)
1692 db_l = Min(db_l, 20);
1693 db_r = Min(db_r, 20);
1695 rhythm[index].volume_l = -(db_l * 2 / 3);
1696 rhythm[index].volume_r = -(db_r * 2 / 3);
1699 void OPNA::SetVolumeADPCM(int db_l, int db_r)
1701 db_l = Min(db_l, 20);
1702 db_r = Min(db_r, 20);
1705 adpcmvol_l = int(65536.0 * pow(10.0, db_l / 40.0));
1709 adpcmvol_r = int(65536.0 * pow(10.0, db_r / 40.0));
1713 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
1714 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
1717 // ---------------------------------------------------------------------------
1719 // in: buffer
\8d\87\90¬
\90æ
1720 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
1722 void OPNA::Mix(Sample* buffer, int nsamples)
1724 FMMix(buffer, nsamples);
1725 psg.Mix(buffer, nsamples);
1726 ADPCMBMix(buffer, nsamples);
1727 RhythmMix(buffer, nsamples);
1730 // ---------------------------------------------------------------------------
1731 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
1733 #define OPNA_STATE_VERSION 2
1735 bool OPNA::ProcessState(void *f, bool loading)
1737 FILEIO *state_fio = (FILEIO *)f;
1739 if(!state_fio->StateCheckUint32(OPNA_STATE_VERSION)) {
1742 if(!OPNABase::ProcessState(f, loading)) {
1745 for(int i = 0; i < 6; i++) {
1746 state_fio->StateUint8(rhythm[i].pan);
1747 state_fio->StateInt8(rhythm[i].level);
1748 state_fio->StateUint32(rhythm[i].pos);
1750 state_fio->StateInt8(rhythmtl);
1751 state_fio->StateInt32(rhythmtvol_l);
1752 state_fio->StateInt32(rhythmtvol_r);
1753 state_fio->StateUint8(rhythmkey);
1758 #endif // BUILD_OPNA
1760 // ---------------------------------------------------------------------------
1762 // ---------------------------------------------------------------------------
1766 // ---------------------------------------------------------------------------
1773 for (int i=0; i<6; i++)
1776 adpcma[i].level = 0;
1777 adpcma[i].volume_l = 0;
1778 adpcma[i].volume_r = 0;
1781 adpcma[i].start = 0;
1783 adpcma[i].adpcmx = 0;
1784 adpcma[i].adpcmd = 0;
1791 adpcmnotice = 0x8000;
1802 // ---------------------------------------------------------------------------
1805 bool OPNB::Init(uint c, uint r, bool ipflag,
1806 uint8 *_adpcma, int _adpcma_size,
1807 uint8 *_adpcmb, int _adpcmb_size)
1810 if (!SetRate(c, r, ipflag))
1812 if (!OPNABase::Init(c, r, ipflag))
1815 adpcmabuf = _adpcma;
1816 adpcmasize = _adpcma_size;
1819 for (i=0; i<=24; i++) // max 16M bytes
1821 if (_adpcmb_size <= (1 << i))
1823 adpcmmask = (1 << i) - 1;
1828 // adpcmmask = _adpcmb_size - 1;
1829 limitaddr = adpcmmask;
1835 SetVolumeADPCMB(0, 0);
1836 SetVolumeADPCMATotal(0, 0);
1838 SetVolumeADPCMA(i, 0, 0);
1843 // ---------------------------------------------------------------------------
1844 //
\83\8a\83Z
\83b
\83g
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;
1869 // ---------------------------------------------------------------------------
1870 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
1872 bool OPNB::SetRate(uint c, uint r, bool ipflag)
1874 if (!OPNABase::SetRate(c, r, ipflag))
1877 adpcmastep = int(double(c) / 54 * 8192 / r);
1881 // ---------------------------------------------------------------------------
1882 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
1884 void OPNB::SetReg(uint addr, uint data)
1890 // omitted registers
1892 case 0x2d: case 0x2e: case 0x2f:
1895 // ADPCM A ---------------------------------------------------------------
1896 case 0x100: // DM/KEYON
1897 if (!(data & 0x80)) // KEY ON
1899 adpcmakey |= data & 0x3f;
1900 for (int c=0; c<6; c++)
1904 ResetStatus(0x100 << c);
1905 adpcma[c].pos = adpcma[c].start;
1906 // adpcma[c].step = 0x10000 - adpcma[c].step;
1908 adpcma[c].adpcmx = 0;
1909 adpcma[c].adpcmd = 0;
1910 adpcma[c].nibble = 0;
1921 adpcmatl = ~data & 63;
1924 case 0x108: case 0x109: case 0x10a:
1925 case 0x10b: case 0x10c: case 0x10d:
1926 adpcma[addr & 7].pan = (data >> 6) & 3;
1927 adpcma[addr & 7].level = ~data & 31;
1930 case 0x110: case 0x111: case 0x112: // START ADDRESS (L)
1931 case 0x113: case 0x114: case 0x115:
1932 case 0x118: case 0x119: case 0x11a: // START ADDRESS (H)
1933 case 0x11b: case 0x11c: case 0x11d:
1934 adpcmareg[addr - 0x110] = data;
1935 adpcma[addr & 7].pos = adpcma[addr & 7].start =
1936 (adpcmareg[(addr&7)+8]*256+adpcmareg[addr&7]) << 9;
1939 case 0x120: case 0x121: case 0x122: // END ADDRESS (L)
1940 case 0x123: case 0x124: case 0x125:
1941 case 0x128: case 0x129: case 0x12a: // END ADDRESS (H)
1942 case 0x12b: case 0x12c: case 0x12d:
1943 adpcmareg[addr - 0x110] = data;
1944 adpcma[addr & 7].stop =
1945 (adpcmareg[(addr&7)+24]*256+adpcmareg[(addr&7)+16] + 1) << 9;
1948 // ADPCMB -----------------------------------------------------------------
1950 if ((data & 0x80) && !adpcmplay)
1953 memaddr = startaddr;
1954 adpcmx = 0, adpcmd = 127;
1959 control1 = data & 0x91;
1963 case 0x11: // Control Register 2
1964 control2 = data & 0xc0;
1967 case 0x12: // Start Address L
1968 case 0x13: // Start Address H
1969 adpcmreg[addr - 0x12 + 0] = data;
1970 startaddr = (adpcmreg[1]*256+adpcmreg[0]) << 9;
1971 memaddr = startaddr;
1974 case 0x14: // Stop Address L
1975 case 0x15: // Stop Address H
1976 adpcmreg[addr - 0x14 + 2] = data;
1977 stopaddr = (adpcmreg[3]*256+adpcmreg[2] + 1) << 9;
1978 // LOG1(" stopaddr %.6x", stopaddr);
1981 case 0x19: // delta-N L
1982 case 0x1a: // delta-N H
1983 adpcmreg[addr - 0x19 + 4] = data;
1984 deltan = adpcmreg[5]*256+adpcmreg[4];
1985 deltan = Max(256, deltan);
1986 adpld = deltan * adplbase >> 16;
1989 case 0x1b: // Level Control
1991 adpcmvolume_l = (adpcmvol_l * adpcmlevel) >> 12;
1992 adpcmvolume_r = (adpcmvol_r * adpcmlevel) >> 12;
1995 case 0x1c: // Flag Control
1996 stmask = ~((data & 0xbf) << 8);
2002 OPNABase::SetReg(addr, data);
2008 // ---------------------------------------------------------------------------
2009 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
2011 uint OPNB::GetReg(uint addr)
2014 return psg.GetReg(addr);
2019 // ---------------------------------------------------------------------------
2020 //
\8ag
\92£
\83X
\83e
\81[
\83^
\83X
\82ð
\93Ç
\82Ý
\82±
\82Þ
2022 uint OPNB::ReadStatusEx()
2024 return (status & stmask) >> 8;
2027 // ---------------------------------------------------------------------------
2030 int OPNB::jedi_table[(48+1)*16];
2032 void OPNB::InitADPCMATable()
2034 const static int8 table2[] =
2036 1, 3, 5, 7, 9, 11, 13, 15,
2037 -1, -3, -5, -7, -9,-11,-13,-15,
2040 for (int i=0; i<=48; i++)
2042 int s = int(16.0 * pow (1.1, i) * 3);
2043 for (int j=0; j<16; j++)
2045 jedi_table[i*16+j] = s * table2[j] / 8;
2050 // ---------------------------------------------------------------------------
2051 // ADPCMA
\8d\87\90¬
2053 void OPNB::ADPCMAMix(Sample* buffer, uint count)
2055 const static int decode_tableA1[16] =
2057 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16,
2058 -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16
2061 if ((adpcmatvol_l < 128 || adpcmatvol_r < 128) && (adpcmakey & 0x3f))
2063 Sample* limit = buffer + count * 2;
2064 for (int i=0; i<6; i++)
2066 ADPCMA& r = adpcma[i];
2067 if ((adpcmakey & (1 << i)) && r.level < 128)
2069 uint mask_l = r.pan & 2 ? -1 : 0;
2070 uint mask_r = r.pan & 1 ? -1 : 0;
2071 if (rhythmmask_ & (1 << i))
2073 mask_l = mask_r = 0;
2076 int db_l = Limit(adpcmatl+adpcmatvol_l+r.level+r.volume_l, 127, -31);
2077 int db_r = Limit(adpcmatl+adpcmatvol_r+r.level+r.volume_r, 127, -31);
2078 int vol_l = tltable[FM_TLPOS+(db_l << (FM_TLBITS-7))] >> 4;
2079 int vol_r = tltable[FM_TLPOS+(db_r << (FM_TLBITS-7))] >> 4;
2081 Sample* dest = buffer;
2082 for ( ; dest<limit; dest+=2)
2084 r.step += adpcmastep;
2085 if (r.pos >= r.stop)
2087 SetStatus(0x100 << i);
2088 adpcmakey &= ~(1<<i);
2092 for (; r.step > 0x10000; r.step -= 0x10000)
2097 r.nibble = adpcmabuf[r.pos>>1];
2098 data = r.nibble >> 4;
2102 data = r.nibble & 0x0f;
2106 r.adpcmx += jedi_table[r.adpcmd + data];
2107 r.adpcmx = Limit(r.adpcmx, 2048*3-1, -2048*3);
2108 r.adpcmd += decode_tableA1[data];
2109 r.adpcmd = Limit(r.adpcmd, 48*16, 0);
2111 int sample_l = (r.adpcmx * vol_l) >> 10;
2112 int sample_r = (r.adpcmx * vol_r) >> 10;
2113 StoreSample(dest[0], sample_l & mask_l);
2114 StoreSample(dest[1], sample_r & mask_r);
2121 // ---------------------------------------------------------------------------
2124 void OPNB::SetVolumeADPCMATotal(int db_l, int db_r)
2126 db_l = Min(db_l, 20);
2127 db_r = Min(db_r, 20);
2129 adpcmatvol_l = -(db_l * 2 / 3);
2130 adpcmatvol_r = -(db_r * 2 / 3);
2133 void OPNB::SetVolumeADPCMA(int index, int db_l, int db_r)
2135 db_l = Min(db_l, 20);
2136 db_r = Min(db_r, 20);
2138 adpcma[index].volume_l = -(db_l * 2 / 3);
2139 adpcma[index].volume_r = -(db_r * 2 / 3);
2142 void OPNB::SetVolumeADPCMB(int db_l, int db_r)
2144 db_l = Min(db_l, 20);
2145 db_r = Min(db_r, 20);
2148 adpcmvol_l = int(65536.0 * pow(10.0, db_l / 40.0));
2152 adpcmvol_r = int(65536.0 * pow(10.0, db_r / 40.0));
2157 // ---------------------------------------------------------------------------
2159 // in: buffer
\8d\87\90¬
\90æ
2160 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
2162 void OPNB::Mix(Sample* buffer, int nsamples)
2164 FMMix(buffer, nsamples);
2165 psg.Mix(buffer, nsamples);
2166 ADPCMBMix(buffer, nsamples);
2167 ADPCMAMix(buffer, nsamples);
2170 #endif // BUILD_OPNB
2172 // ---------------------------------------------------------------------------
2173 // YM2612 common part
2174 // ---------------------------------------------------------------------------
2176 #if defined(BUILD_OPN2)
2178 int OPN2Base::amtable[FM_LFOENTS] = { -1, };
2179 int OPN2Base::pmtable[FM_LFOENTS];
2181 int32 OPN2Base::tltable[FM_TLENTS+FM_TLPOS];
2182 bool OPN2Base::tablehasmade = false;
2184 OPN2Base::OPN2Base()
2189 for (int i=0; i<6; i++)
2191 ch[i].SetChip(&chip);
2192 ch[i].SetType(typeN);
2196 OPN2Base::~OPN2Base()
2200 // ---------------------------------------------------------------------------
2203 bool OPN2Base::Init(uint c, uint r, bool)
2215 // ---------------------------------------------------------------------------
2216 //
\83e
\81[
\83u
\83\8b\8dì
\90¬
2218 void OPN2Base::MakeTable2()
2222 for (int i=-FM_TLPOS; i<FM_TLENTS; i++)
2224 tltable[i+FM_TLPOS] = uint(65536. * pow(2.0, i * -16. / FM_TLENTS))-1;
2227 tablehasmade = true;
2231 // ---------------------------------------------------------------------------
2232 //
\83\8a\83Z
\83b
\83g
2234 void OPN2Base::Reset()
2239 for (i=0x20; i<0x28; i++) SetReg(i, 0);
2240 for (i=0x30; i<0xc0; i++) SetReg(i, 0);
2241 for (i=0x130; i<0x1c0; i++) SetReg(i, 0);
2242 for (i=0x100; i<0x110; i++) SetReg(i, 0);
2243 for (i=0x10; i<0x20; i++) SetReg(i, 0);
2257 // ---------------------------------------------------------------------------
2258 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
2260 bool OPN2Base::SetRate(uint c, uint r, bool)
2262 c /= 2; //
\8f]
\97\88\94Å
\82Æ
\82Ì
\8cÝ
\8a·
\90«
\82ð
\8fd
\8e\8b\82µ
\82½
\82¯
\82è
\82á
\83R
\83\81\83\93\83g
\83A
\83E
\83g
\82µ
\82æ
\82¤
2264 OPNBase::Init(c, r);
2268 lfodcount = reg22 & 0x08 ? lfotable[reg22 & 7] : 0;
2273 // ---------------------------------------------------------------------------
2274 //
\83`
\83\83\83\93\83l
\83\8b\83}
\83X
\83N
\82Ì
\90Ý
\92è
2276 void OPN2Base::SetChannelMask(uint mask)
2278 for (int i=0; i<6; i++)
2279 ch[i].Mute(!!(mask & (1 << i)));
2282 // ---------------------------------------------------------------------------
2283 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
2285 void OPN2Base::SetReg(uint addr, uint data)
2292 // Timer -----------------------------------------------------------------
2293 case 0x24: case 0x25:
2294 SetTimerA(addr, data);
2302 SetTimerControl(data);
2305 // Misc ------------------------------------------------------------------
2306 case 0x28: // Key On/Off
2309 c = (data & 3) + (data & 4 ? 3 : 0);
2310 ch[c].KeyControl(data >> 4);
2314 // Status Mask -----------------------------------------------------------
2317 // UpdateStatus(); //?
2320 // Prescaler -------------------------------------------------------------
2321 case 0x2d: case 0x2e: case 0x2f:
2322 SetPrescaler(addr-0x2d);
2325 // F-Number --------------------------------------------------------------
2326 case 0x1a0: case 0x1a1: case 0x1a2:
2328 case 0xa0: case 0xa1: case 0xa2:
2329 fnum[c] = data + fnum2[c] * 0x100;
2330 ch[c].SetFNum(fnum[c]);
2333 case 0x1a4: case 0x1a5: case 0x1a6:
2335 case 0xa4 : case 0xa5: case 0xa6:
2336 fnum2[c] = uint8(data);
2339 case 0xa8: case 0xa9: case 0xaa:
2340 fnum3[c] = data + fnum2[c+6] * 0x100;
2343 case 0xac : case 0xad: case 0xae:
2344 fnum2[c+6] = uint8(data);
2347 // Algorithm -------------------------------------------------------------
2349 case 0x1b0: case 0x1b1: case 0x1b2:
2351 case 0xb0: case 0xb1: case 0xb2:
2352 ch[c].SetFB((data >> 3) & 7);
2353 ch[c].SetAlgorithm(data & 7);
2356 case 0x1b4: case 0x1b5: case 0x1b6:
2358 case 0xb4: case 0xb5: case 0xb6:
2359 pan[c] = (data >> 6) & 3;
2363 // LFO -------------------------------------------------------------------
2365 modified = reg22 ^ data;
2369 lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0;
2372 // PSG -------------------------------------------------------------------
2373 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
2374 case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
2377 //
\89¹
\90F ------------------------------------------------------------------
2383 OPNBase::SetParameter(&ch[c], addr, data);
2389 // ---------------------------------------------------------------------------
2390 //
\83X
\83e
\81[
\83^
\83X
\83t
\83\89\83O
\90Ý
\92è
2392 void OPN2Base::SetStatus(uint bits)
2394 if (!(status & bits))
2396 // LOG2("SetStatus(%.2x %.2x)\n", bits, stmask);
2397 status |= bits & stmask;
2401 // LOG1("SetStatus(%.2x) - ignored\n", bits);
2404 void OPN2Base::ResetStatus(uint bits)
2407 // LOG1("ResetStatus(%.2x)\n", bits);
2411 inline void OPN2Base::UpdateStatus()
2413 // LOG2("%d:INT = %d\n", Diag::GetCPUTick(), (status & stmask & reg29) != 0);
2414 Intr((status & stmask & reg29) != 0);
2417 // ---------------------------------------------------------------------------
2419 // in: buffer
\8d\87\90¬
\90æ
2420 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
2422 void OPN2Base::FMMix(Sample* buffer, int nsamples)
2424 if (fmvolume_l > 0 || fmvolume_r > 0)
2428 if (!(regtc & 0xc0))
2429 csmch->SetFNum(fnum[csmch-ch]);
2432 //
\8cø
\89Ê
\89¹
\83\82\81[
\83h
2433 csmch->op[0].SetFNum(fnum3[1]); csmch->op[1].SetFNum(fnum3[2]);
2434 csmch->op[2].SetFNum(fnum3[0]); csmch->op[3].SetFNum(fnum[2]);
2437 int act = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare();
2439 act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6;
2440 if (!(reg22 & 0x08))
2445 Mix6(buffer, nsamples, act);
2450 // ---------------------------------------------------------------------------
2452 void OPN2Base::MixSubSL(int activech, ISample** dest)
2454 if (activech & 0x001) (*dest[0] = ch[0].CalcL());
2455 if (activech & 0x004) (*dest[1] += ch[1].CalcL());
2456 if (activech & 0x010) (*dest[2] += ch[2].CalcL());
2457 if (activech & 0x040) (*dest[3] += ch[3].CalcL());
2458 if (activech & 0x100) (*dest[4] += ch[4].CalcL());
2459 if (activech & 0x400) (*dest[5] += ch[5].CalcL());
2462 inline void OPN2Base::MixSubS(int activech, ISample** dest)
2464 if (activech & 0x001) (*dest[0] = ch[0].Calc());
2465 if (activech & 0x004) (*dest[1] += ch[1].Calc());
2466 if (activech & 0x010) (*dest[2] += ch[2].Calc());
2467 if (activech & 0x040) (*dest[3] += ch[3].Calc());
2468 if (activech & 0x100) (*dest[4] += ch[4].Calc());
2469 if (activech & 0x400) (*dest[5] += ch[5].Calc());
2472 // ---------------------------------------------------------------------------
2474 void OPN2Base::BuildLFOTable()
2476 if (amtable[0] == -1)
2478 for (int c=0; c<256; c++)
2481 if (c < 0x40) v = c * 2 + 0x80;
2482 else if (c < 0xc0) v = 0x7f - (c - 0x40) * 2 + 0x80;
2483 else v = (c - 0xc0) * 2;
2486 if (c < 0x80) v = 0xff - c * 2;
2487 else v = (c - 0x80) * 2;
2488 amtable[c] = v & ~3;
2493 // ---------------------------------------------------------------------------
2495 inline void OPN2Base::LFO()
2497 // LOG3("%4d - %8d, %8d\n", c, lfocount, lfodcount);
2499 // Operator::SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
2500 // Operator::SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
2501 chip.SetPML(pmtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
2502 chip.SetAML(amtable[(lfocount >> (FM_LFOCBITS+1)) & 0xff]);
2503 lfocount += lfodcount;
2506 // ---------------------------------------------------------------------------
2509 //#define IStoSampleL(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_l) >> 14)
2510 //#define IStoSampleR(s) ((Limit(s, 0x7fff, -0x8000) * fmvolume_r) >> 14)
2512 void OPN2Base::Mix6(Sample* buffer, int nsamples, int activech)
2517 idest[0] = &ibuf[pan[0]];
2518 idest[1] = &ibuf[pan[1]];
2519 idest[2] = &ibuf[pan[2]];
2520 idest[3] = &ibuf[pan[3]];
2521 idest[4] = &ibuf[pan[4]];
2522 idest[5] = &ibuf[pan[5]];
2524 Sample* limit = buffer + nsamples * 2;
2525 for (Sample* dest = buffer; dest < limit; dest+=2)
2527 ibuf[1] = ibuf[2] = ibuf[3] = 0;
2528 if (activech & 0xaaa)
2529 LFO(), MixSubSL(activech, idest);
2531 MixSubS(activech, idest);
2532 StoreSample(dest[0], IStoSampleL(ibuf[2] + ibuf[3]));
2533 StoreSample(dest[1], IStoSampleR(ibuf[1] + ibuf[3]));
2536 // ---------------------------------------------------------------------------
2537 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
2539 #define OPN2_BASE_STATE_VERSION 1
2541 bool OPN2Base::ProcessState(void *f, bool loading)
2543 FILEIO *state_fio = (FILEIO *)f;
2545 if(!state_fio->StateCheckUint32(OPN2_BASE_STATE_VERSION)) {
2548 if(!OPNBase::ProcessState(f, loading)) {
2551 state_fio->StateBuffer(pan, sizeof(pan), 1);
2552 state_fio->StateBuffer(fnum2, sizeof(fnum2), 1);
2553 state_fio->StateUint8(reg22);
2554 state_fio->StateUint32(reg29);
2555 state_fio->StateUint32(stmask);
2556 state_fio->StateUint32(statusnext);
2557 state_fio->StateUint32(lfocount);
2558 state_fio->StateUint32(lfodcount);
2559 state_fio->StateBuffer(fnum, sizeof(fnum), 1);
2560 state_fio->StateBuffer(fnum3, sizeof(fnum3), 1);
2563 // Make force-restore around prescaler and timers. 20180625 K.O
2564 uint bak = prescale;
2568 for(int i = 0; i < 6; i++) {
2569 if(!ch[i].ProcessState(f, loading)) {
2575 #endif // defined(BUILD_OPN2)
2577 // ---------------------------------------------------------------------------
2579 // ---------------------------------------------------------------------------
2583 // ---------------------------------------------------------------------------
2584 //
\83\8c\83W
\83X
\83^
\8eæ
\93¾
2586 uint OPN2::GetReg(uint addr)
2591 // ---------------------------------------------------------------------------
2596 csmch = &ch[2]; // ToDo: Check register.
2598 // ---------------------------------------------------------------------------
2604 // ---------------------------------------------------------------------------
2607 bool OPN2::Init(uint c, uint r, bool ipflag, const _TCHAR* path)
2610 if (!SetRate(c, r, ipflag))
2612 if (!OPN2Base::Init(c, r, ipflag))
2618 // ---------------------------------------------------------------------------
2619 //
\83\8a\83Z
\83b
\83g
2626 // ---------------------------------------------------------------------------
2627 //
\83T
\83\93\83v
\83\8a\83\93\83O
\83\8c\81[
\83g
\95Ï
\8dX
2629 bool OPN2::SetRate(uint c, uint r, bool ipflag)
2631 if (!OPN2Base::SetRate(c, r, ipflag))
2636 // ---------------------------------------------------------------------------
2637 //
\83\8c\83W
\83X
\83^
\83A
\83\8c\83C
\82É
\83f
\81[
\83^
\82ð
\90Ý
\92è
2639 void OPN2::SetReg(uint addr, uint data)
2647 // UpdateStatus(); //?
2651 OPN2Base::SetReg(addr, data);
2658 // ---------------------------------------------------------------------------
2660 // in: buffer
\8d\87\90¬
\90æ
2661 // nsamples
\8d\87\90¬
\83T
\83\93\83v
\83\8b\90\94
2663 void OPN2::Mix(Sample* buffer, int nsamples)
2665 // ToDo: Implement ch.6 as PCM.
2666 FMMix(buffer, nsamples);
2669 // ---------------------------------------------------------------------------
2670 //
\83X
\83e
\81[
\83g
\83Z
\81[
\83u
2672 #define OPN2_STATE_VERSION 1
2674 bool OPN2::ProcessState(void *f, bool loading)
2676 return OPN2Base::ProcessState(f, loading);
2679 #endif // BUILD_OPN2