aica: make sure lpf cutoff value is > 0

Issue #108
This commit is contained in:
Flyinghead 2020-08-31 21:53:33 +02:00
parent 493a833f56
commit d7b1ad61f3
4 changed files with 82 additions and 114 deletions

View File

@ -64,35 +64,33 @@ s32 DYNACALL UNPACK(u16 val)
void DecodeInst(u32 *IPtr,_INST *i)
{
i->TRA=(IPtr[0]>>9)&0x7F;
i->TWT=(IPtr[0]>>8)&0x01;
i->TWA=(IPtr[0]>>1)&0x7F;
i->TRA = (IPtr[0] >> 9) & 0x7F;
i->TWT = IPtr[0] & 0x100;
i->TWA = (IPtr[0] >> 1) & 0x7F;
i->XSEL=(IPtr[1]>>15)&0x01;
i->YSEL=(IPtr[1]>>13)&0x03;
i->IRA=(IPtr[1]>>7)&0x3F;
i->IWT=(IPtr[1]>>6)&0x01;
i->IWA=(IPtr[1]>>1)&0x1F;
i->XSEL = IPtr[1] & 0x8000;
i->YSEL = (IPtr[1] >> 13) & 3;
i->IRA = (IPtr[1] >> 7) & 0x3F;
i->IWT = IPtr[1] & 0x40;
i->IWA = (IPtr[1] >> 1) & 0x1F;
i->TABLE=(IPtr[2]>>15)&0x01;
i->MWT=(IPtr[2]>>14)&0x01;
i->MRD=(IPtr[2]>>13)&0x01;
i->EWT=(IPtr[2]>>12)&0x01;
i->EWA=(IPtr[2]>>8)&0x0F;
i->ADRL=(IPtr[2]>>7)&0x01;
i->FRCL=(IPtr[2]>>6)&0x01;
i->SHIFT=(IPtr[2]>>4)&0x03;
i->YRL=(IPtr[2]>>3)&0x01;
i->NEGB=(IPtr[2]>>2)&0x01;
i->ZERO=(IPtr[2]>>1)&0x01;
i->BSEL=(IPtr[2]>>0)&0x01;
i->TABLE = IPtr[2] & 0x8000;
i->MWT = IPtr[2] & 0x4000;
i->MRD = IPtr[2] & 0x2000;
i->EWT = IPtr[2] & 0x1000;
i->EWA = (IPtr[2] >> 8) & 0x0F;
i->ADRL = IPtr[2] & 0x80;
i->FRCL = IPtr[2] & 0x40;
i->SHIFT = (IPtr[2] >> 4) & 3;
i->YRL = IPtr[2] & 8;
i->NEGB = IPtr[2] & 4;
i->ZERO = IPtr[2] & 2;
i->BSEL = IPtr[2] & 1;
i->NOFL=(IPtr[3]>>15)&1; //????
//i->COEF=(IPtr[3]>>9)&0x3f;
i->MASA=(IPtr[3]>>9)&0x3f; //???
i->ADREB=(IPtr[3]>>8)&0x1;
i->NXADR=(IPtr[3]>>7)&0x1;
i->NOFL = IPtr[3] & 0x8000;
i->MASA = (IPtr[3] >> 9) & 0x3f;
i->ADREB = IPtr[3] & 0x100;
i->NXADR = IPtr[3] & 0x80;
}
#if HOST_CPU == CPU_X86 && FEAT_DSPREC == DYNAREC_JIT

View File

@ -94,33 +94,33 @@ void dsp_writenmem(u32 addr);
struct _INST
{
unsigned int TRA;
unsigned int TWT;
unsigned int TWA;
u8 TRA;
bool TWT;
u8 TWA;
unsigned int XSEL;
unsigned int YSEL;
unsigned int IRA;
unsigned int IWT;
unsigned int IWA;
bool XSEL;
u8 YSEL;
u8 IRA;
bool IWT;
u8 IWA;
unsigned int EWT;
unsigned int EWA;
unsigned int ADRL;
unsigned int FRCL;
unsigned int SHIFT;
unsigned int YRL;
unsigned int NEGB;
unsigned int ZERO;
unsigned int BSEL;
bool EWT;
u8 EWA;
bool ADRL;
bool FRCL;
u8 SHIFT;
bool YRL;
bool NEGB;
bool ZERO;
bool BSEL;
unsigned int NOFL; //MRQ set
unsigned int TABLE; //MRQ set
unsigned int MWT; //MRQ set
unsigned int MRD; //MRQ set
unsigned int MASA; //MRQ set
unsigned int ADREB; //MRQ set
unsigned int NXADR; //MRQ set
bool NOFL; //MRQ set
bool TABLE; //MRQ set
bool MWT; //MRQ set
bool MRD; //MRQ set
u8 MASA; //MRQ set
bool ADREB; //MRQ set
bool NXADR; //MRQ set
};
void DecodeInst(u32 *IPtr,_INST *i);

View File

@ -38,7 +38,6 @@ void AICADSP_Step(struct dsp_t *DSP)
s32 FRC_REG = 0; //13 bit
s32 Y_REG = 0; //24 bit
u32 ADRS_REG = 0; //13 bit
int step;
memset(DSPData->EFREG, 0, sizeof(DSPData->EFREG));
@ -52,7 +51,7 @@ void AICADSP_Step(struct dsp_t *DSP)
f = fopen("dsp.txt", "wt");
#endif
for (step = 0; step < 128; ++step)
for (int step = 0; step < 128; ++step)
{
u32 *IPtr = DSPData->MPRO + step * 4;
@ -60,38 +59,29 @@ void AICADSP_Step(struct dsp_t *DSP)
{
// Empty instruction shortcut
X = DSP->TEMP[DSP->regs.MDEC_CT & 0x7F];
X <<= 8;
X >>= 8;
Y = FRC_REG;
Y <<= 19;
Y >>= 19;
s64 v = ((s64)X * (s64)Y) >> 10;
v <<= 6; // 26 bits only
v >>= 6;
ACC = v + X;
ACC <<= 6; // 26 bits only
ACC >>= 6;
ACC = (((s64)X * (s64)Y) >> 12) + X;
continue;
}
u32 TRA = (IPtr[0] >> 9) & 0x7F;
u32 TWT = (IPtr[0] >> 8) & 0x01;
bool TWT = IPtr[0] & 0x100;
u32 XSEL = (IPtr[1] >> 15) & 0x01;
u32 YSEL = (IPtr[1] >> 13) & 0x03;
bool XSEL = IPtr[1] & 0x8000;
u32 YSEL = (IPtr[1] >> 13) & 3;
u32 IRA = (IPtr[1] >> 7) & 0x3F;
u32 IWT = (IPtr[1] >> 6) & 0x01;
bool IWT = IPtr[1] & 0x40;
u32 EWT = (IPtr[2] >> 12) & 0x01;
u32 ADRL = (IPtr[2] >> 7) & 0x01;
u32 FRCL = (IPtr[2] >> 6) & 0x01;
u32 SHIFT = (IPtr[2] >> 4) & 0x03;
u32 YRL = (IPtr[2] >> 3) & 0x01;
u32 NEGB = (IPtr[2] >> 2) & 0x01;
u32 ZERO = (IPtr[2] >> 1) & 0x01;
u32 BSEL = (IPtr[2] >> 0) & 0x01;
bool EWT = IPtr[2] & 0x1000;
bool ADRL = IPtr[2] & 0x80;
bool FRCL = IPtr[2] & 0x40;
u32 SHIFT = (IPtr[2] >> 4) & 3;
bool YRL = IPtr[2] & 8;
bool NEGB = IPtr[2] & 4;
bool ZERO = IPtr[2] & 2;
bool BSEL = IPtr[2] & 1;
u32 COEF = step;
@ -128,9 +118,6 @@ void AICADSP_Step(struct dsp_t *DSP)
{
u32 IWA = (IPtr[1] >> 1) & 0x1F;
DSP->MEMS[IWA] = MEMVAL[step & 3]; // MEMVAL was selected in previous MRD
// "When read and write are specified simultaneously in the same step for INPUTS, TEMP, etc., write is executed after read."
//if (IRA == IWA)
// INPUTS = MEMVAL[step & 3];
}
// Operand sel
@ -170,30 +157,13 @@ void AICADSP_Step(struct dsp_t *DSP)
// Shifter
// There's a 1-step delay at the output of the X*Y + B adder. So we use the ACC value from the previous step.
if (SHIFT == 0)
{
if (SHIFT == 0 || SHIFT == 3)
SHIFTED = ACC;
if (SHIFTED > 0x007FFFFF)
SHIFTED = 0x007FFFFF;
if (SHIFTED < (-0x00800000))
SHIFTED = -0x00800000;
}
else if (SHIFT == 1)
{
else
SHIFTED = ACC << 1; // x2 scale
if (SHIFTED > 0x007FFFFF)
SHIFTED = 0x007FFFFF;
if (SHIFTED < (-0x00800000))
SHIFTED = -0x00800000;
}
else if (SHIFT == 2)
{
SHIFTED = ACC << 1; // x2 scale
}
else if (SHIFT == 3)
{
SHIFTED = ACC;
}
if (SHIFT < 2)
SHIFTED = std::min(std::max(SHIFTED, -0x00800000), 0x007FFFFF);
// ACCUM
ACC = (((s64)X * (s64)Y) >> 12) + B;
@ -214,18 +184,18 @@ void AICADSP_Step(struct dsp_t *DSP)
if (step & 1)
{
u32 MWT = (IPtr[2] >> 14) & 0x01;
u32 MRD = (IPtr[2] >> 13) & 0x01;
bool MWT = IPtr[2] & 0x4000;
bool MRD = IPtr[2] & 0x2000;
if (MRD || MWT)
{
u32 TABLE = (IPtr[2] >> 15) & 0x01;
bool TABLE = IPtr[2] & 0x8000;
u32 NOFL = (IPtr[3] >> 15) & 1; //????
verify(!NOFL);
u32 MASA = (IPtr[3] >> 9) & 0x3f; //???
u32 ADREB = (IPtr[3] >> 8) & 0x1;
u32 NXADR = (IPtr[3] >> 7) & 0x1;
//bool NOFL = IPtr[3] & 0x8000;
//verify(!NOFL);
u32 MASA = (IPtr[3] >> 9) & 0x3f;
bool ADREB = IPtr[3] & 0x100;
bool NXADR = IPtr[3] & 0x80;
u32 ADDR = DSPData->MADRS[MASA];
if (ADREB)

View File

@ -472,6 +472,7 @@ struct ChannelEx
{
u32 fv = FEG.GetValue();
s32 f = (((fv & 0xFF) | 0x100) << 4) >> ((fv >> 8) ^ 0x1F);
f = std::max(1, f);
sample = f * sample + (0x2000 - f + FEG.q) * FEG.prev1 - FEG.q * FEG.prev2;
sample >>= 13;
clip16(sample);
@ -510,9 +511,10 @@ struct ChannelEx
clip_verify(((s16)oLeft)==oLeft);
clip_verify(((s16)oRight)==oRight);
clip_verify((oDsp << 12) >> 12 == oDsp);
clip_verify(sample*oLeft>=0);
clip_verify(sample*oRight>=0);
clip_verify(sample*oDsp>=0);
clip_verify((s64)sample*oDsp>=0);
StepAEG(this);
StepFEG(this);
@ -733,7 +735,7 @@ struct ChannelEx
VolMix.DSPAtt = total_level + SendLevel[ccd->IMXL];
}
//Q,FLV0,FLV1,FLV2,FLV3,FLV4,FAR,FD1R,FD2R,FRR
//Q,FLV0,FLV1,FLV2,FLV3,FLV4,FAR,FD1R,FD2R,FRR, LPOFF
void UpdateFEG()
{
FEG.active = ccd->LPOFF == 0
@ -821,7 +823,7 @@ struct ChannelEx
UpdateAtts();
break;
case 0x28://Q
case 0x28://Q, LPOFF
case 0x29://TL
if (size == 2 || offset == 0x28)
UpdateFEG();
@ -1534,10 +1536,8 @@ void AICA_Sample()
//Sample is ready ! clip/saturate and store :}
#ifdef CLIP_WARN
if (((s16)mixl) != mixl)
printf("Clipped mixl %d\n",mixl);
if (((s16)mixr) != mixr)
printf("Clipped mixr %d\n",mixr);
if (((s16)mixl) != mixl || ((s16)mixr) != mixr)
printf("Clipped mixl %d mixr %d\n", mixl, mixr);
#endif
clip16(mixl);