YM2608-LLE, part 11
now with per-channel osc
This commit is contained in:
parent
ff9d5370c5
commit
4fab971b7d
9
extern/YM2608-LLE/fmopna_impl.c
vendored
9
extern/YM2608-LLE/fmopna_impl.c
vendored
|
@ -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 = 0;
|
||||||
chip->o_analog += volume_lut[sign_a ? 0 : vol_a];
|
chip->o_analog += chip->o_analog_ch[0] = volume_lut[sign_a ? 0 : vol_a];
|
||||||
chip->o_analog += volume_lut[sign_b ? 0 : vol_b];
|
chip->o_analog += chip->o_analog_ch[1] = volume_lut[sign_b ? 0 : vol_b];
|
||||||
chip->o_analog += volume_lut[sign_c ? 0 : vol_c];
|
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;
|
chip->ac_rss_load = chip->rss_cnt2[1] == 0;
|
||||||
|
|
||||||
|
// tildearrow: per-channel osc
|
||||||
|
chip->last_rss_sample = rss_sample & 0xffff;
|
||||||
}
|
}
|
||||||
if (chip->rss_eclk2)
|
if (chip->rss_eclk2)
|
||||||
{
|
{
|
||||||
|
|
3
extern/YM2608-LLE/fmopna_impl.h
vendored
3
extern/YM2608-LLE/fmopna_impl.h
vendored
|
@ -845,6 +845,8 @@ typedef struct {
|
||||||
int sh1_l;
|
int sh1_l;
|
||||||
int sh2_l;
|
int sh2_l;
|
||||||
int opo_fm;
|
int opo_fm;
|
||||||
|
|
||||||
|
int last_rss_sample;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int busy_cnt[2];
|
int busy_cnt[2];
|
||||||
|
@ -932,6 +934,7 @@ typedef struct {
|
||||||
|
|
||||||
#ifndef FMOPNA_YM2612
|
#ifndef FMOPNA_YM2612
|
||||||
float o_analog;
|
float o_analog;
|
||||||
|
float o_analog_ch[3];
|
||||||
int o_sh1;
|
int o_sh1;
|
||||||
int o_sh2;
|
int o_sh2;
|
||||||
int o_opo;
|
int o_opo;
|
||||||
|
|
|
@ -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
|
// ac_fm_output
|
||||||
void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
|
void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
|
||||||
|
thread_local int fmOut[6];
|
||||||
|
|
||||||
for (size_t h=0; h<len; h++) {
|
for (size_t h=0; h<len; h++) {
|
||||||
bool have0=false;
|
bool have0=false;
|
||||||
bool have1=false;
|
bool have1=false;
|
||||||
unsigned char howLong=0;
|
unsigned char howLong=0;
|
||||||
unsigned char subCycle=0x100-12;
|
signed char subCycle=0;
|
||||||
unsigned char subSubCycle=0;
|
unsigned char subSubCycle=0;
|
||||||
|
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
fmOut[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
bool canWeWrite=fm_lle.prescaler_latch[1]&1;
|
bool canWeWrite=fm_lle.prescaler_latch[1]&1;
|
||||||
|
|
||||||
lastS=fm_lle.o_s;
|
|
||||||
lastSH=fm_lle.o_sh1;
|
|
||||||
lastSH2=fm_lle.o_sh2;
|
|
||||||
|
|
||||||
if (canWeWrite) {
|
if (canWeWrite) {
|
||||||
if (delay>0) {
|
if (delay>0) {
|
||||||
if (delay==3) {
|
if (delay==3) {
|
||||||
|
@ -563,10 +570,18 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
|
||||||
|
|
||||||
if (++subSubCycle>=6) {
|
if (++subSubCycle>=6) {
|
||||||
subSubCycle=0;
|
subSubCycle=0;
|
||||||
if (subCycle<12) {
|
if (subCycle>=0 && subCycle<6 && fm_lle.ac_fm_output_en) {
|
||||||
oscBuf[subCycle]->data[oscBuf[subCycle]->needle++]=fm_lle.ac_fm_output;
|
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) {
|
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>>=1;
|
||||||
dacVal|=(fm_lle.o_opo&1)<<14;
|
dacVal|=(fm_lle.o_opo&1)<<15;
|
||||||
howLong++;
|
howLong++;
|
||||||
|
|
||||||
|
lastSH=fm_lle.o_sh1;
|
||||||
|
lastSH2=fm_lle.o_sh2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fm_lle.o_sh1 && lastSH) {
|
lastS=fm_lle.o_s;
|
||||||
if (dacVal&0x2000) { // positive
|
|
||||||
int e=(dacVal>>10)&7;
|
|
||||||
int m=(dacVal>>0)&1023;
|
|
||||||
dacOut[0]=m<<e;
|
|
||||||
if (e) dacOut[0]+=512<<e;
|
|
||||||
} else { // negative
|
|
||||||
int e=((dacVal>>10)&7)^7;
|
|
||||||
int m=((dacVal>>0)&1023)^1023;
|
|
||||||
dacOut[0]=-(m<<e);
|
|
||||||
if (e) dacOut[0]-=512<<e;
|
|
||||||
}
|
|
||||||
//int e=(dacVal>>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<<e);
|
|
||||||
if (e) dacOut[1]+=512<<e;
|
|
||||||
} else { // negative
|
|
||||||
int e=((dacVal>>10)&7)^7;
|
|
||||||
int m=((dacVal>>0)&1023)^1023;
|
|
||||||
dacOut[1]=-(m<<e);
|
|
||||||
if (e) dacOut[1]-=512<<e;
|
|
||||||
}
|
|
||||||
have1=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ADPCM data bus
|
// ADPCM data bus
|
||||||
// thanks nukeykt
|
// thanks nukeykt
|
||||||
|
@ -643,12 +639,32 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
|
||||||
//logW("NOT 48! %d",howLong);
|
//logW("NOT 48! %d",howLong);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DAC
|
// chan osc
|
||||||
int accm1=dacOut[0];
|
// FM
|
||||||
int accm2=dacOut[1];
|
for (int i=0; i<6; i++) {
|
||||||
|
if (fmOut[i]<-32768) fmOut[i]=-32768;
|
||||||
|
if (fmOut[i]>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;
|
||||||
|
|
||||||
int outL=(accm1<<1)+fm_lle.o_analog*ssgVol*42;
|
// DAC
|
||||||
int outR=(accm2<<1)+fm_lle.o_analog*ssgVol*42;
|
int accm1=(short)dacOut[0];
|
||||||
|
int accm2=(short)dacOut[1];
|
||||||
|
|
||||||
|
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<-32768) outL=-32768;
|
||||||
if (outL>32767) outL=32767;
|
if (outL>32767) outL=32767;
|
||||||
|
@ -1745,6 +1761,12 @@ void DivPlatformYM2608::reset() {
|
||||||
writeRSSOff=0;
|
writeRSSOff=0;
|
||||||
writeRSSOn=0;
|
writeRSSOn=0;
|
||||||
globalRSSVolume=0x3f;
|
globalRSSVolume=0x3f;
|
||||||
|
rssCycle=0;
|
||||||
|
rssSubCycle=0;
|
||||||
|
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
rssOut[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
delay=0;
|
delay=0;
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,11 @@ class DivPlatformYM2608: public DivPlatformOPN {
|
||||||
unsigned int dacVal;
|
unsigned int dacVal;
|
||||||
unsigned int dacVal2;
|
unsigned int dacVal2;
|
||||||
int dacOut[2];
|
int dacOut[2];
|
||||||
|
int rssOut[6];
|
||||||
bool lastSH;
|
bool lastSH;
|
||||||
bool lastSH2;
|
bool lastSH2;
|
||||||
bool lastS;
|
bool lastS;
|
||||||
unsigned char cas, ras;
|
unsigned char cas, ras, rssCycle, rssSubCycle;
|
||||||
unsigned short adMemAddr;
|
unsigned short adMemAddr;
|
||||||
int adReadCount;
|
int adReadCount;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue