diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 1eb05b814..c38838266 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -97,7 +97,7 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) { } for (int i=0; i<4; i++) { // run DMA - if (amiga.dmaEn && amiga.audEn[i]) { + if (amiga.dmaEn && amiga.audEn[i] && !amiga.audIr[i]) { amiga.audTick[i]-=AMIGA_DIVIDER; if (amiga.audTick[i]<0) { amiga.audTick[i]+=MAX(AMIGA_DIVIDER,amiga.audPer[i]); @@ -139,7 +139,10 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) { amiga.dmaLoc[i]+=2; // check for length if ((--amiga.dmaLen[i])==0) { - if (amiga.audInt[i]) irq(i); + if (amiga.audInt[i]) { + amiga.audIr[i]=true; + irq(i); + } amiga.dmaLoc[i]=amiga.audLoc[i]; amiga.dmaLen[i]=amiga.audLen[i]; } @@ -179,7 +182,21 @@ void DivPlatformAmiga::acquire(short** buf, size_t len) { } void DivPlatformAmiga::irq(int ch) { - + // disable interrupt + rWrite(0x9a,128<=0 && chan[i].samplesong.sampleLen) { DivSample* s=parent->getSample(chan[i].sample); - chWrite(i,0,sampleOff[chan[i].sample]>>16); - chWrite(i,2,sampleOff[chan[i].sample]); - chWrite(i,4,MIN(65535,s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)>>1)); + int start=chan[i].audPos&(~1); + if (start>s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)) start=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT); + int len=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)-start; + if (len<0) len=0; + if (len>131070) len=131070; + len>>=1; + + start+=sampleOff[chan[i].sample]; + + if (len<1) { + chWrite(i,0,0); + chWrite(i,2,0x400); + chWrite(i,4,1); + } else { + chWrite(i,0,start>>16); + chWrite(i,2,start); + chWrite(i,4,len); + } + rWrite(0x96,0x8000|(1<isLoopable()) { int loopPos=(sampleOff[chan[i].sample]+s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT))&(~1); int loopEnd=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)-s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT))>>1; - chWrite(i,0,loopPos>>16); - chWrite(i,2,loopPos); - chWrite(i,4,MIN(65535,loopEnd)); + chan[i].irLocH=loopPos>>16; + chan[i].irLocL=loopPos; + chan[i].irLen=MIN(65535,loopEnd); } else { - chWrite(i,0,0); - chWrite(i,2,i<<8); - chWrite(i,4,1); + chan[i].irLocH=0; + chan[i].irLocL=0x400; + chan[i].irLen=1; } + rWrite(0x9a,0x8000|(128<& wlist) { } unsigned char* DivPlatformAmiga::getRegisterPool() { + // update DMACONR + regPool[1]=( + (amiga.audEn[0]?1:0)| + (amiga.audEn[1]?2:0)| + (amiga.audEn[2]?4:0)| + (amiga.audEn[3]?8:0)| + (amiga.dmaEn?512:0) + ); + + // update ADKCONR + regPool[0x10>>1]=( + (amiga.useV[0]?1:0)| + (amiga.useV[1]?2:0)| + (amiga.useV[2]?4:0)| + (amiga.useV[3]?8:0)| + (amiga.useP[0]?16:0)| + (amiga.useP[1]?32:0)| + (amiga.useP[2]?64:0)| + (amiga.useP[3]?128:0) + ); + + // update INTENAR + regPool[0x1c>>1]=( + (amiga.audInt[0]?128:0)| + (amiga.audInt[1]?256:0)| + (amiga.audInt[2]?512:0)| + (amiga.audInt[3]?1024:0)| + 16384 // INTEN + ); + + // update INTREQR + regPool[0x1e>>1]=( + (amiga.audIr[0]?128:0)| + (amiga.audIr[1]?256:0)| + (amiga.audIr[2]?512:0)| + (amiga.audIr[3]?1024:0) + ); + return (unsigned char*)regPool; } @@ -722,7 +823,8 @@ void DivPlatformAmiga::renderSamples(int sysID) { memset(sampleLoaded,0,256*sizeof(bool)); // first 1024 bytes reserved for wavetable - size_t memPos=1024; + // the next 2 bytes are reserved for end of sample + size_t memPos=1026; for (int i=0; isong.sampleLen; i++) { DivSample* s=parent->song.sample[i]; if (!s->renderOn[0][sysID]) { diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index db9c2b65b..a34feea87 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -26,7 +26,7 @@ class DivPlatformAmiga: public DivDispatch { struct Channel: public SharedChannel { - unsigned short audLen; + unsigned short audLen, irLocL, irLocH, irLen; unsigned int audPos; int audSub; unsigned char volPos; @@ -36,6 +36,9 @@ class DivPlatformAmiga: public DivDispatch { Channel(): SharedChannel(64), audLen(0), + irLocL(0), + irLocH(0), + irLen(2), audPos(0), audSub(0), volPos(0), @@ -59,6 +62,7 @@ class DivPlatformAmiga: public DivDispatch { struct Amiga { // register state bool audInt[4]; // interrupt on + bool audIr[4]; // interrupt request bool audEn[4]; // audio DMA on bool useP[4]; // period modulation bool useV[4]; // volume modulation