X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=plugins%2Fdfsound%2Fregisters.c;h=bcac4d9ad63d8e95e4d7b48204447482d8125819;hb=3c7a8977ddbdbfb4a8840a487fadade29bd939d6;hp=4588fa7c29f518c881d31f5e7d36c7e8028f91a6;hpb=05c7cec77522f04857f655474574469a5e66661d;p=pcsx_rearmed.git diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c index 4588fa7c..bcac4d9a 100644 --- a/plugins/dfsound/registers.c +++ b/plugins/dfsound/registers.c @@ -22,6 +22,7 @@ #include "externals.h" #include "registers.h" #include "spu_config.h" +#include "spu.h" static void SoundOn(int start,int end,unsigned short val); static void SoundOff(int start,int end,unsigned short val); @@ -36,17 +37,19 @@ static void ReverbOn(int start,int end,unsigned short val); // WRITE REGISTERS: called by main emu //////////////////////////////////////////////////////////////////////// -static const uint32_t ignore_dupe[8] = { +static const uint32_t ignore_dupe[16] = { // ch 0-15 c40 c80 cc0 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, // ch 16-24 d40 control reverb - 0x7f7f7f7f, 0x7f7f7f7f, 0xff05ff0f, 0xffffffff + 0x7f7f7f7f, 0x7f7f7f7f, 0xff05ff0f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, unsigned int cycles) { - int r = reg & 0xfff; + int r = reg & 0xffe; int rofs = (r - 0xc00) >> 1; int changed = spu.regArea[rofs] != val; spu.regArea[rofs] = val; @@ -112,23 +115,32 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, //------------------------------------------------// case 14: // loop? spu.s_chan[ch].pLoop=spu.spuMemC+((val&~1)<<3); + spu.s_chan[ch].bIgnoreLoop = 1; goto upd_irq; //------------------------------------------------// } return; } + else if (0x0e00 <= r && r < 0x0e60) + { + int ch = (r >> 2) & 0x1f; + log_unhandled("c%02d w %cvol %04x\n", ch, (r & 2) ? 'r' : 'l', val); + spu.s_chan[ch].iVolume[(r >> 1) & 1] = (signed short)val >> 1; + } switch(r) { //-------------------------------------------------// case H_SPUaddr: spu.spuAddr = (unsigned long) val<<3; + //check_irq_io(spu.spuAddr); break; //-------------------------------------------------// case H_SPUdata: - *(unsigned short *)(spu.spuMemC + spu.spuAddr) = val; + *(unsigned short *)(spu.spuMemC + spu.spuAddr) = HTOLE16(val); spu.spuAddr += 2; spu.spuAddr &= 0x7fffe; + check_irq_io(spu.spuAddr); break; //-------------------------------------------------// case H_SPUctrl: @@ -145,21 +157,13 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, break; //-------------------------------------------------// case H_SPUReverbAddr: - if(val==0xFFFF || val<=0x200) - {spu.rvb->StartAddr=spu.rvb->CurrAddr=0;} - else - { - const long iv=(unsigned long)val<<2; - if(spu.rvb->StartAddr!=iv) - { - spu.rvb->StartAddr=(unsigned long)val<<2; - spu.rvb->CurrAddr=spu.rvb->StartAddr; - } - } goto rvbd; //-------------------------------------------------// case H_SPUirqAddr: - spu.pSpuIrq=spu.spuMemC+(((unsigned long) val<<3)&~0xf); + //if (val & 1) + // log_unhandled("w irq with lsb: %08lx %04x\n", reg, val); + spu.pSpuIrq = spu.spuMemC + (((int)val << 3) & ~0xf); + //check_irq_io(spu.spuAddr); goto upd_irq; //-------------------------------------------------// case H_SPUrvolL: @@ -171,6 +175,17 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, break; //-------------------------------------------------// + case H_SPUmvolL: + case H_SPUmvolR: + if (val & 0x8000) + log_unhandled("w master sweep: %08lx %04x\n", reg, val); + break; + + case 0x0dac: + if (val != 4) + log_unhandled("1f801dac %04x\n", val); + break; + /* case H_ExtLeft: //auxprintf("EL %d\n",val); @@ -214,12 +229,12 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, break; //-------------------------------------------------// case H_CDLeft: - spu.iLeftXAVol=val & 0x7fff; - if(spu.cddavCallback) spu.cddavCallback(0,val); + spu.iLeftXAVol=(int16_t)val; + if(spu.cddavCallback) spu.cddavCallback(0,(int16_t)val); break; case H_CDRight: - spu.iRightXAVol=val & 0x7fff; - if(spu.cddavCallback) spu.cddavCallback(1,val); + spu.iRightXAVol=(int16_t)val; + if(spu.cddavCallback) spu.cddavCallback(1,(int16_t)val); break; //-------------------------------------------------// case H_FMod1: @@ -246,38 +261,38 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, ReverbOn(16,24,val); break; //-------------------------------------------------// - case H_Reverb+0 : spu.rvb->FB_SRC_A=val*4; goto rvbd; - case H_Reverb+2 : spu.rvb->FB_SRC_B=val*4; goto rvbd; - case H_Reverb+4 : spu.rvb->IIR_ALPHA=(short)val; goto rvbd; - case H_Reverb+6 : spu.rvb->ACC_COEF_A=(short)val; goto rvbd; - case H_Reverb+8 : spu.rvb->ACC_COEF_B=(short)val; goto rvbd; - case H_Reverb+10 : spu.rvb->ACC_COEF_C=(short)val; goto rvbd; - case H_Reverb+12 : spu.rvb->ACC_COEF_D=(short)val; goto rvbd; - case H_Reverb+14 : spu.rvb->IIR_COEF=(short)val; goto rvbd; - case H_Reverb+16 : spu.rvb->FB_ALPHA=(short)val; goto rvbd; - case H_Reverb+18 : spu.rvb->FB_X=(short)val; goto rvbd; - case H_Reverb+20 : spu.rvb->IIR_DEST_A0=val*4; goto rvbd; - case H_Reverb+22 : spu.rvb->IIR_DEST_A1=val*4; goto rvbd; - case H_Reverb+24 : spu.rvb->ACC_SRC_A0=val*4; goto rvbd; - case H_Reverb+26 : spu.rvb->ACC_SRC_A1=val*4; goto rvbd; - case H_Reverb+28 : spu.rvb->ACC_SRC_B0=val*4; goto rvbd; - case H_Reverb+30 : spu.rvb->ACC_SRC_B1=val*4; goto rvbd; - case H_Reverb+32 : spu.rvb->IIR_SRC_A0=val*4; goto rvbd; - case H_Reverb+34 : spu.rvb->IIR_SRC_A1=val*4; goto rvbd; - case H_Reverb+36 : spu.rvb->IIR_DEST_B0=val*4; goto rvbd; - case H_Reverb+38 : spu.rvb->IIR_DEST_B1=val*4; goto rvbd; - case H_Reverb+40 : spu.rvb->ACC_SRC_C0=val*4; goto rvbd; - case H_Reverb+42 : spu.rvb->ACC_SRC_C1=val*4; goto rvbd; - case H_Reverb+44 : spu.rvb->ACC_SRC_D0=val*4; goto rvbd; - case H_Reverb+46 : spu.rvb->ACC_SRC_D1=val*4; goto rvbd; - case H_Reverb+48 : spu.rvb->IIR_SRC_B1=val*4; goto rvbd; - case H_Reverb+50 : spu.rvb->IIR_SRC_B0=val*4; goto rvbd; - case H_Reverb+52 : spu.rvb->MIX_DEST_A0=val*4; goto rvbd; - case H_Reverb+54 : spu.rvb->MIX_DEST_A1=val*4; goto rvbd; - case H_Reverb+56 : spu.rvb->MIX_DEST_B0=val*4; goto rvbd; - case H_Reverb+58 : spu.rvb->MIX_DEST_B1=val*4; goto rvbd; - case H_Reverb+60 : spu.rvb->IN_COEF_L=(short)val; goto rvbd; - case H_Reverb+62 : spu.rvb->IN_COEF_R=(short)val; goto rvbd; + case H_Reverb+0 : goto rvbd; + case H_Reverb+2 : goto rvbd; + case H_Reverb+4 : spu.rvb->IIR_ALPHA=(short)val; break; + case H_Reverb+6 : spu.rvb->ACC_COEF_A=(short)val; break; + case H_Reverb+8 : spu.rvb->ACC_COEF_B=(short)val; break; + case H_Reverb+10 : spu.rvb->ACC_COEF_C=(short)val; break; + case H_Reverb+12 : spu.rvb->ACC_COEF_D=(short)val; break; + case H_Reverb+14 : spu.rvb->IIR_COEF=(short)val; break; + case H_Reverb+16 : spu.rvb->FB_ALPHA=(short)val; break; + case H_Reverb+18 : spu.rvb->FB_X=(short)val; break; + case H_Reverb+20 : goto rvbd; + case H_Reverb+22 : goto rvbd; + case H_Reverb+24 : goto rvbd; + case H_Reverb+26 : goto rvbd; + case H_Reverb+28 : goto rvbd; + case H_Reverb+30 : goto rvbd; + case H_Reverb+32 : goto rvbd; + case H_Reverb+34 : goto rvbd; + case H_Reverb+36 : goto rvbd; + case H_Reverb+38 : goto rvbd; + case H_Reverb+40 : goto rvbd; + case H_Reverb+42 : goto rvbd; + case H_Reverb+44 : goto rvbd; + case H_Reverb+46 : goto rvbd; + case H_Reverb+48 : goto rvbd; + case H_Reverb+50 : goto rvbd; + case H_Reverb+52 : goto rvbd; + case H_Reverb+54 : goto rvbd; + case H_Reverb+56 : goto rvbd; + case H_Reverb+58 : goto rvbd; + case H_Reverb+60 : spu.rvb->IN_COEF_L=(short)val; break; + case H_Reverb+62 : spu.rvb->IN_COEF_R=(short)val; break; } return; @@ -296,7 +311,7 @@ rvbd: unsigned short CALLBACK SPUreadRegister(unsigned long reg) { - const unsigned long r=reg&0xfff; + const unsigned long r = reg & 0xffe; if(r>=0x0c00 && r<0x0d80) { @@ -306,7 +321,7 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) { const int ch=(r>>4)-0xc0; if(spu.dwNewChannel&(1<>16); @@ -319,6 +334,13 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) } } } + else if (0x0e00 <= r && r < 0x0e60) + { + int ch = (r >> 2) & 0x1f; + int v = spu.s_chan[ch].iVolume[(r >> 1) & 1] << 1; + log_unhandled("c%02d r %cvol %04x\n", ch, (r & 2) ? 'r' : 'l', v); + return v; + } switch(r) { @@ -326,16 +348,18 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) return spu.spuCtrl; case H_SPUstat: - return spu.spuStat; + return (spu.spuStat & ~0x3F) | (spu.spuCtrl & 0x3F); case H_SPUaddr: return (unsigned short)(spu.spuAddr>>3); + // this reportedly doesn't work on real hw case H_SPUdata: { - unsigned short s = *(unsigned short *)(spu.spuMemC + spu.spuAddr); + unsigned short s = LE16TOH(*(unsigned short *)(spu.spuMemC + spu.spuAddr)); spu.spuAddr += 2; spu.spuAddr &= 0x7fffe; + //check_irq_io(spu.spuAddr); return s; } @@ -345,6 +369,23 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) //case H_SPUIsOn2: // return IsSoundOn(16,24); + case H_SPUMute1: + case H_SPUMute2: + log_unhandled("r isOn: %08lx\n", reg); + break; + + case 0x0dac: + case H_SPUirqAddr: + case H_CDLeft: + case H_CDRight: + case H_ExtLeft: + case H_ExtRight: + break; + + default: + if (r >= 0xda0) + log_unhandled("spu r %08lx\n", reg); + break; } return spu.regArea[(r-0xc00)>>1]; @@ -360,10 +401,9 @@ static void SoundOn(int start,int end,unsigned short val) for(ch=start;ch>=1) // loop channels { - if((val&1) && regAreaGet(ch,6)) // mmm... start has to be set before key on !?! + if((val&1) && regAreaGetCh(ch, 6)) // mmm... start has to be set before key on !?! { - spu.s_chan[ch].pCurr=spu.spuMemC+((regAreaGet(ch,6)&~1)<<3); // must be block aligned - spu.s_chan[ch].pLoop=spu.spuMemC+((regAreaGet(ch,14)&~1)<<3); + spu.s_chan[ch].bIgnoreLoop = 0; spu.dwNewChannel|=(1< sweep up? + log_unhandled("ch%d sweepl %04x\n", ch, vol); if(vol&0x2000) sInc=-1; // -> or down? if(vol&0x1000) vol^=0xffff; // -> mmm... phase inverted? have to investigate this vol=((vol&0x7f)+1)/2; // -> sweep: 0..127 -> 0..64 @@ -457,6 +498,7 @@ static void SetVolumeL(unsigned char ch,short vol) // LEFT VOLUME vol&=0x3fff; spu.s_chan[ch].iLeftVolume=vol; // store volume + //spu.regArea[(0xe00-0xc00)/2 + ch*2 + 0] = vol << 1; } //////////////////////////////////////////////////////////////////////// @@ -468,6 +510,7 @@ static void SetVolumeR(unsigned char ch,short vol) // RIGHT VOLUME if(vol&0x8000) // comments... see above :) { short sInc=1; + log_unhandled("ch%d sweepr %04x\n", ch, vol); if(vol&0x2000) sInc=-1; if(vol&0x1000) vol^=0xffff; vol=((vol&0x7f)+1)/2; @@ -483,6 +526,7 @@ static void SetVolumeR(unsigned char ch,short vol) // RIGHT VOLUME vol&=0x3fff; spu.s_chan[ch].iRightVolume=vol; + //spu.regArea[(0xe00-0xc00)/2 + ch*2 + 1] = vol << 1; } //////////////////////////////////////////////////////////////////////// @@ -495,11 +539,12 @@ static void SetPitch(int ch,unsigned short val) // SET PITCH if(val>0x3fff) NP=0x3fff; // get pitch val else NP=val; - spu.s_chan[ch].iRawPitch=NP; - spu.s_chan[ch].sinc=(NP<<4)|8; - spu.s_chan[ch].sinc_inv=0; - if (spu_config.iUseInterpolation == 1) - spu.SB[ch * SB_SIZE + 32] = 1; // -> freq change in simple interpolation mode: set flag + spu.s_chan[ch].iRawPitch = NP; + spu.s_chan[ch].sinc = NP << 4; + spu.s_chan[ch].sinc_inv = 0; + spu.s_chan[ch].bNewPitch = 1; + + // don't mess spu.dwChannelsAudible as adsr runs independently } ////////////////////////////////////////////////////////////////////////