X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=plugins%2Fdfsound%2Fregisters.c;h=2796f9c3f5b5bc1b189ca205f78724ba9e3836e4;hb=38e4048faeaccf7fdc6084f64866f2ea52bb97f1;hp=580589975d334784b681f7f05af343adb5c87542;hpb=906b1599387d4ecbf225282ba5123f83444c88fb;p=pcsx_rearmed.git diff --git a/plugins/dfsound/registers.c b/plugins/dfsound/registers.c index 58058997..2796f9c3 100644 --- a/plugins/dfsound/registers.c +++ b/plugins/dfsound/registers.c @@ -37,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; @@ -58,7 +60,7 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, if (val == 0 && (r & 0xff8) == 0xd88) return; - do_samples_if_needed(cycles, 0); + do_samples_if_needed(cycles, 0, 16); if(r>=0x0c00 && r<0x0d80) // some channel info? { @@ -119,18 +121,26 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, } 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) = HTOLE16(val); spu.spuAddr += 2; spu.spuAddr &= 0x7fffe; + check_irq_io(spu.spuAddr); break; //-------------------------------------------------// case H_SPUctrl: @@ -152,7 +162,8 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, case H_SPUirqAddr: //if (val & 1) // log_unhandled("w irq with lsb: %08lx %04x\n", reg, val); - spu.pSpuIrq=spu.spuMemC+(((unsigned long) val<<3)&~0xf); + spu.pSpuIrq = spu.spuMemC + (((int)val << 3) & ~0xf); + //check_irq_io(spu.spuAddr); goto upd_irq; //-------------------------------------------------// case H_SPUrvolL: @@ -202,10 +213,12 @@ void CALLBACK SPUwriteRegister(unsigned long reg, unsigned short val, */ //-------------------------------------------------// case H_SPUon1: + do_samples_if_needed(cycles, 0, 2); SoundOn(0,16,val); break; //-------------------------------------------------// - case H_SPUon2: + case H_SPUon2: + do_samples_if_needed(cycles, 0, 2); SoundOn(16,24,val); break; //-------------------------------------------------// @@ -298,9 +311,9 @@ rvbd: // READ REGISTER: called by main emu //////////////////////////////////////////////////////////////////////// -unsigned short CALLBACK SPUreadRegister(unsigned long reg) +unsigned short CALLBACK SPUreadRegister(unsigned long reg, unsigned int cycles) { - const unsigned long r=reg&0xfff; + const unsigned long r = reg & 0xffe; if(r>=0x0c00 && r<0x0d80) { @@ -308,12 +321,13 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) { case 12: // get adsr vol { - const int ch=(r>>4)-0xc0; - if(spu.dwNewChannel&(1<>16); + // this used to return 1 immediately after keyon to deal with + // some poor timing, but that causes Rayman 2 to lose track of + // it's channels on busy scenes and start looping some of them forever + const int ch = (r>>4) - 0xc0; + if (spu.s_chan[ch].bStarting) + do_samples_if_needed(cycles, 0, 2); + return (unsigned short)(spu.s_chan[ch].ADSRX.EnvelopeVol >> 16); } case 14: // get loop address @@ -323,6 +337,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) { @@ -335,11 +356,13 @@ unsigned short CALLBACK SPUreadRegister(unsigned long reg) case H_SPUaddr: return (unsigned short)(spu.spuAddr>>3); + // this reportedly doesn't work on real hw case H_SPUdata: { unsigned short s = LE16TOH(*(unsigned short *)(spu.spuMemC + spu.spuAddr)); spu.spuAddr += 2; spu.spuAddr &= 0x7fffe; + //check_irq_io(spu.spuAddr); return s; } @@ -384,6 +407,7 @@ static void SoundOn(int start,int end,unsigned short val) if((val&1) && regAreaGetCh(ch, 6)) // mmm... start has to be set before key on !?! { spu.s_chan[ch].bIgnoreLoop = 0; + spu.s_chan[ch].bStarting = 1; spu.dwNewChannel|=(1<