diff --git a/extern/YM2608-LLE/fmopna_impl.c b/extern/YM2608-LLE/fmopna_impl.c index f629a5479..187918c39 100644 --- a/extern/YM2608-LLE/fmopna_impl.c +++ b/extern/YM2608-LLE/fmopna_impl.c @@ -2430,10 +2430,11 @@ void FMOPNA_2612_Clock(fmopna_2612_t* chip, int clk) }; + // tildearrow: per-channel oscilloscope for SSG chip->o_analog = 0; - chip->o_analog += volume_lut[sign_a ? 0 : vol_a]; - chip->o_analog += volume_lut[sign_b ? 0 : vol_b]; - chip->o_analog += volume_lut[sign_c ? 0 : vol_c]; + chip->o_analog += chip->o_analog_ch[0] = volume_lut[sign_a ? 0 : vol_a]; + chip->o_analog += chip->o_analog_ch[1] = volume_lut[sign_b ? 0 : vol_b]; + chip->o_analog += chip->o_analog_ch[2] = volume_lut[sign_c ? 0 : vol_c]; } { @@ -5368,6 +5369,8 @@ void FMOPNA_2612_Clock(fmopna_2612_t* chip, int clk) chip->ac_rss_load = chip->rss_cnt2[1] == 0; + // tildearrow: per-channel osc + chip->last_rss_sample = rss_sample & 0xffff; } if (chip->rss_eclk2) { diff --git a/extern/YM2608-LLE/fmopna_impl.h b/extern/YM2608-LLE/fmopna_impl.h index 05c4ee73c..96bd713a4 100644 --- a/extern/YM2608-LLE/fmopna_impl.h +++ b/extern/YM2608-LLE/fmopna_impl.h @@ -845,6 +845,8 @@ typedef struct { int sh1_l; int sh2_l; int opo_fm; + + int last_rss_sample; #endif int busy_cnt[2]; @@ -932,6 +934,7 @@ typedef struct { #ifndef FMOPNA_YM2612 float o_analog; + float o_analog_ch[3]; int o_sh1; int o_sh2; int o_opo; diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 9cef86b93..66637475c 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -490,21 +490,28 @@ void DivPlatformYM2608::acquire_ymfm(short** buf, size_t len) { } } +static const unsigned char subCycleMap[6]={ + 3, 4, 5, 0, 1, 2 +}; + // ac_fm_output void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { + thread_local int fmOut[6]; + for (size_t h=0; h0) { if (delay==3) { @@ -563,10 +570,18 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { if (++subSubCycle>=6) { subSubCycle=0; - if (subCycle<12) { - oscBuf[subCycle]->data[oscBuf[subCycle]->needle++]=fm_lle.ac_fm_output; + if (subCycle>=0 && subCycle<6 && fm_lle.ac_fm_output_en) { + fmOut[subCycleMap[subCycle]]+=((short)fm_lle.ac_fm_output)<<2; + } + if (++subCycle>=6) subCycle=0; + } + + if (fm_lle.rss_eclk1) { + if (++rssSubCycle>=24) { + rssSubCycle=0; + rssOut[rssCycle]=(short)fm_lle.last_rss_sample; + if (++rssCycle>=6) rssCycle=0; } - subCycle++; } if (canWeWrite) { @@ -577,45 +592,26 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) { } } } + if (!fm_lle.o_s && lastS) { + if (!fm_lle.o_sh1 && lastSH) { + dacOut[0]=dacVal^0x8000; + have0=true; + } + + if (!fm_lle.o_sh2 && lastSH2) { + dacOut[1]=dacVal^0x8000; + have1=true; + } - if (fm_lle.o_s && !lastS) { dacVal>>=1; - dacVal|=(fm_lle.o_opo&1)<<14; + dacVal|=(fm_lle.o_opo&1)<<15; howLong++; + + lastSH=fm_lle.o_sh1; + lastSH2=fm_lle.o_sh2; } - if (!fm_lle.o_sh1 && lastSH) { - if (dacVal&0x2000) { // positive - int e=(dacVal>>10)&7; - int m=(dacVal>>0)&1023; - dacOut[0]=m<>10)&7)^7; - int m=((dacVal>>0)&1023)^1023; - dacOut[0]=-(m<>10)&7; - //int m=(dacVal>>0)&1023; - //m-=512; - have0=true; - } - - if (!fm_lle.o_sh2 && lastSH2) { - if (dacVal&0x2000) { // positive - int e=(dacVal>>10)&7; - int m=(dacVal>>0)&1023; - dacOut[1]=(m<>10)&7)^7; - int m=((dacVal>>0)&1023)^1023; - dacOut[1]=-(m<32767) fmOut[i]=32767; + oscBuf[i]->data[oscBuf[i]->needle++]=fmOut[i]; + } + // SSG + for (int i=0; i<3; i++) { + oscBuf[i+6]->data[oscBuf[i+6]->needle++]=fm_lle.o_analog_ch[i]*32767; + } + // RSS + for (int i=0; i<6; i++) { + if (rssOut[i]<-32768) rssOut[i]=-32768; + if (rssOut[i]>32767) rssOut[i]=32767; + oscBuf[9+i]->data[oscBuf[9+i]->needle++]=rssOut[i]; + } + // ADPCM + oscBuf[15]->data[oscBuf[15]->needle++]=fm_lle.ac_ad_output; // DAC - int accm1=dacOut[0]; - int accm2=dacOut[1]; + int accm1=(short)dacOut[0]; + int accm2=(short)dacOut[1]; - int outL=(accm1<<1)+fm_lle.o_analog*ssgVol*42; - int outR=(accm2<<1)+fm_lle.o_analog*ssgVol*42; + int outL=(accm1)+fm_lle.o_analog*ssgVol*42; + int outR=(accm2)+fm_lle.o_analog*ssgVol*42; if (outL<-32768) outL=-32768; if (outL>32767) outL=32767; @@ -1745,6 +1761,12 @@ void DivPlatformYM2608::reset() { writeRSSOff=0; writeRSSOn=0; globalRSSVolume=0x3f; + rssCycle=0; + rssSubCycle=0; + + for (int i=0; i<6; i++) { + rssOut[i]=0; + } delay=0; diff --git a/src/engine/platform/ym2608.h b/src/engine/platform/ym2608.h index f50d19cbd..bc1ddeaba 100644 --- a/src/engine/platform/ym2608.h +++ b/src/engine/platform/ym2608.h @@ -57,10 +57,11 @@ class DivPlatformYM2608: public DivPlatformOPN { unsigned int dacVal; unsigned int dacVal2; int dacOut[2]; + int rssOut[6]; bool lastSH; bool lastSH2; bool lastS; - unsigned char cas, ras; + unsigned char cas, ras, rssCycle, rssSubCycle; unsigned short adMemAddr; int adReadCount;