diff --git a/core/hw/aica/dsp.cpp b/core/hw/aica/dsp.cpp index bf9f8ff24..84a32ff7c 100644 --- a/core/hw/aica/dsp.cpp +++ b/core/hw/aica/dsp.cpp @@ -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 diff --git a/core/hw/aica/dsp.h b/core/hw/aica/dsp.h index 0517318e7..99444086f 100644 --- a/core/hw/aica/dsp.h +++ b/core/hw/aica/dsp.h @@ -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); diff --git a/core/hw/aica/dsp_interp.cpp b/core/hw/aica/dsp_interp.cpp index a3a7db062..625036a80 100644 --- a/core/hw/aica/dsp_interp.cpp +++ b/core/hw/aica/dsp_interp.cpp @@ -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) diff --git a/core/hw/aica/sgc_if.cpp b/core/hw/aica/sgc_if.cpp index 1843aa873..1084a4d18 100755 --- a/core/hw/aica/sgc_if.cpp +++ b/core/hw/aica/sgc_if.cpp @@ -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);