diff --git a/doc/7-systems/bifurcator.md b/doc/7-systems/bifurcator.md new file mode 100644 index 000000000..bb1465a92 --- /dev/null +++ b/doc/7-systems/bifurcator.md @@ -0,0 +1,3 @@ +# Bifurcator + + diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 7f0671177..3419f988c 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -492,12 +492,92 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) { void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { for (size_t h=0; h0) { + if (delay>1) { + delay--; + } else { + fm_lle.input.cs=0; + fm_lle.input.rd=0; + fm_lle.input.wr=1; + fm_lle.input.a0=0; + fm_lle.input.a1=0; + delay=1; + } + } else if (!writes.empty()) { + QueuedWrite& w=writes.front(); + if (w.addrOrVal) { + fm_lle.input.cs=0; + fm_lle.input.rd=1; + fm_lle.input.wr=0; + fm_lle.input.a1=w.addr>>8; + fm_lle.input.a0=1; + fm_lle.input.data=w.val; + + delay=32; + + //logV("%.3x = %.2x",w.addr,w.val); + + regPool[w.addr&0x1ff]=w.val; + writes.pop_front(); + } else { + fm_lle.input.cs=0; + fm_lle.input.rd=1; + fm_lle.input.wr=0; + fm_lle.input.a1=w.addr>>8; + fm_lle.input.a0=0; + fm_lle.input.data=w.addr&0xff; + + delay=32; + + w.addrOrVal=true; + } + } + + FMOPNA_Clock(&fm_lle,0); + FMOPNA_Clock(&fm_lle,1); + + if (delay==1) { + // check busy status here + if (!(fm_lle.o_data&0x80)) { + delay=0; + } else { + //logV("AM BUSY"); + } + } + + if (fm_lle.o_s && !lastS) { + dacVal>>=1; + dacVal|=(fm_lle.o_opo&1)<<16; + } + + if (!fm_lle.o_sh1 && lastSH) { + /*int e=(dacVal>>10)&7; + int m=(dacVal>>0)&1023; + dacOut[0]=dacVal-0x10000;//(m<>1; + logV("%.8x (%d, %d)",dacVal,m,e); + dacVal=0;*/ + break; + } + + // ADPCM data bus + //if (fm_lle.input.!=0) { + //logV("%x",fm_lle.input.ad); + //} + } + + // TODO: o_analog + + // DAC + buf[0][h]=fm_lle.ac_fm_accm1[0]>>1; + buf[1][h]=buf[0][h]; } } - void DivPlatformYM2608::tick(bool sysTick) { // FM for (int i=0; i<6; i++) { @@ -1533,6 +1613,46 @@ void DivPlatformYM2608::reset() { pendingWrites[i]=-1; } + if (useCombo==2) { + fm_lle.input.cs=1; + fm_lle.input.rd=0; + fm_lle.input.wr=0; + fm_lle.input.a0=0; + fm_lle.input.a1=0; + fm_lle.input.data=0; + fm_lle.input.ad=0; + fm_lle.input.da=0; + fm_lle.input.dm=0; + fm_lle.input.test=1; + fm_lle.input.dt0=0; + + fm_lle.input.ic=1; + for (size_t h=0; h<576; h++) { + FMOPNA_Clock(&fm_lle,0); + FMOPNA_Clock(&fm_lle,1); + } + + fm_lle.input.ic=0; + for (size_t h=0; h<576; h++) { + FMOPNA_Clock(&fm_lle,0); + FMOPNA_Clock(&fm_lle,1); + } + + fm_lle.input.ic=1; + for (size_t h=0; h<576; h++) { + FMOPNA_Clock(&fm_lle,0); + FMOPNA_Clock(&fm_lle,1); + } + + dacVal=0; + dacVal2=0; + dacOut[0]=0; + dacOut[1]=0; + lastSH=false; + lastSH2=false; + lastS=false; + } + lastBusy=60; lfoValue=8; sampleBank=0; @@ -1702,7 +1822,11 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) { fbAllOps=flags.getBool("fbAllOps",false); ssgVol=flags.getInt("ssgVol",128); fmVol=flags.getInt("fmVol",256); - rate=fm->sample_rate(chipClock); + if (useCombo==2) { + rate=chipClock/144; + } else { + rate=fm->sample_rate(chipClock); + } for (int i=0; i<16; i++) { oscBuf[i]->rate=rate; } @@ -1710,6 +1834,8 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) { immWrite(prescale,0xff); ay->setExtClockDiv(chipClock,ayDiv); ay->setFlags(ayFlags); + + logV("CLOCK: %d RATE: %d",chipClock,rate); } int DivPlatformYM2608::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { diff --git a/src/engine/platform/ym2608.h b/src/engine/platform/ym2608.h index 9c4a67336..c1bacb74a 100644 --- a/src/engine/platform/ym2608.h +++ b/src/engine/platform/ym2608.h @@ -54,6 +54,12 @@ class DivPlatformYM2608: public DivPlatformOPN { ymfm::ym2608* fm; ymfm::ym2608::output_data fmout; fmopna_t fm_lle; + unsigned int dacVal; + unsigned int dacVal2; + int dacOut[2]; + bool lastSH; + bool lastSH2; + bool lastS; unsigned char* adpcmBMem; size_t adpcmBMemLen;