diff --git a/src/engine/export/amigaValidation.cpp b/src/engine/export/amigaValidation.cpp index 56d3814a7..e1aa4dfdb 100644 --- a/src/engine/export/amigaValidation.cpp +++ b/src/engine/export/amigaValidation.cpp @@ -149,7 +149,7 @@ std::vector DivExportAmigaValidation::go(DivEngine* e) { } else if (waveNum<65536) { seq->writeC((i<<4)|4); seq->writeS_BE(waveNum); - } else{ + } else { seq->writeC((i<<4)|1); seq->writeC(waves[waveNum].pos>>16); seq->writeC(waves[waveNum].pos>>8); diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index a4e279dad..67853d902 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -81,7 +81,18 @@ const char** DivPlatformAmiga::getRegisterSheet() { void DivPlatformAmiga::acquire(short** buf, size_t len) { thread_local int outL, outR, output; + for (size_t h=0; h>1]=val; - - if (!skipRegisterWrites && dumpWrites) { - addWrite(addr,val); - } - switch (addr&0x1fe) { case 0x96: { // DMACON if (val&32768) { - if (val&1) amiga.audEn[0]=true; - if (val&2) amiga.audEn[1]=true; - if (val&4) amiga.audEn[2]=true; - if (val&8) amiga.audEn[3]=true; - if (val&512) amiga.dmaEn=true; + if (val&1) audEn[0]=true; + if (val&2) audEn[1]=true; + if (val&4) audEn[2]=true; + if (val&8) audEn[3]=true; + if (val&512) dmaEn=true; } else { if (val&1) { - amiga.audEn[0]=false; - UPDATE_DMA(0); + audEn[0]=false; } if (val&2) { - amiga.audEn[1]=false; - UPDATE_DMA(1); + audEn[1]=false; } if (val&4) { - amiga.audEn[2]=false; - UPDATE_DMA(2); + audEn[2]=false; } if (val&8) { - amiga.audEn[3]=false; - UPDATE_DMA(3); + audEn[3]=false; } if (val&512) { - amiga.dmaEn=false; + dmaEn=false; } } break; } case 0x9a: { // INTENA if (val&32768) { - if (val&128) amiga.audInt[0]=true; - if (val&256) amiga.audInt[1]=true; - if (val&512) amiga.audInt[2]=true; - if (val&1024) amiga.audInt[3]=true; + if (val&128) audInt[0]=true; + if (val&256) audInt[1]=true; + if (val&512) audInt[2]=true; + if (val&1024) audInt[3]=true; } else { - if (val&128) amiga.audInt[0]=false; - if (val&256) amiga.audInt[1]=false; - if (val&512) amiga.audInt[2]=false; - if (val&1024) amiga.audInt[3]=false; + if (val&128) audInt[0]=false; + if (val&256) audInt[1]=false; + if (val&512) audInt[2]=false; + if (val&1024) audInt[3]=false; } break; } case 0x9c: { // INTREQ if (val&32768) { if (val&128) { - amiga.audIr[0]=true; - irq(0); + audIr[0]=true; } if (val&256) { - amiga.audIr[1]=true; - irq(1); + audIr[1]=true; } if (val&512) { - amiga.audIr[2]=true; - irq(2); + audIr[2]=true; } if (val&1024) { - amiga.audIr[3]=true; - irq(3); + audIr[3]=true; } } else { - if (val&128) amiga.audIr[0]=false; - if (val&256) amiga.audIr[1]=false; - if (val&512) amiga.audIr[2]=false; - if (val&1024) amiga.audIr[3]=false; + if (val&128) audIr[0]=false; + if (val&256) audIr[1]=false; + if (val&512) audIr[2]=false; + if (val&1024) audIr[3]=false; } break; } case 0x9e: { // ADKCON if (val&32768) { - if (val&1) amiga.useV[0]=true; - if (val&2) amiga.useV[1]=true; - if (val&4) amiga.useV[2]=true; - if (val&8) amiga.useV[3]=true; - if (val&16) amiga.useP[0]=true; - if (val&32) amiga.useP[1]=true; - if (val&64) amiga.useP[2]=true; - if (val&128) amiga.useP[3]=true; + if (val&1) useV[0]=true; + if (val&2) useV[1]=true; + if (val&4) useV[2]=true; + if (val&8) useV[3]=true; + if (val&16) useP[0]=true; + if (val&32) useP[1]=true; + if (val&64) useP[2]=true; + if (val&128) useP[3]=true; } else { - if (val&1) amiga.useV[0]=false; - if (val&2) amiga.useV[1]=false; - if (val&4) amiga.useV[2]=false; - if (val&8) amiga.useV[3]=false; - if (val&16) amiga.useP[0]=false; - if (val&32) amiga.useP[1]=false; - if (val&64) amiga.useP[2]=false; - if (val&128) amiga.useP[3]=false; + if (val&1) useV[0]=false; + if (val&2) useV[1]=false; + if (val&4) useV[2]=false; + if (val&8) useV[3]=false; + if (val&16) useP[0]=false; + if (val&32) useP[1]=false; + if (val&64) useP[2]=false; + if (val&128) useP[3]=false; } break; } @@ -316,31 +315,31 @@ void DivPlatformAmiga::rWrite(unsigned short addr, unsigned short val) { bool updateDMA=false; switch (addr&15) { case 0: // LCH - amiga.audLoc[ch]&=0xffff; - amiga.audLoc[ch]|=val<<16; + audLoc[ch]&=0xffff; + audLoc[ch]|=val<<16; updateDMA=true; break; case 2: // LCL - amiga.audLoc[ch]&=0xffff0000; - amiga.audLoc[ch]|=val&0xfffe; + audLoc[ch]&=0xffff0000; + audLoc[ch]|=val&0xfffe; updateDMA=true; break; case 4: // LEN - amiga.audLen[ch]=val; + audLen[ch]=val; updateDMA=true; break; case 6: // PER - amiga.audPer[ch]=val; + audPer[ch]=val; break; case 8: // VOL - amiga.audVol[ch]=val; + audVol[ch]=val; break; case 10: // DAT - amiga.audDat[0][ch]=val&0xff; - amiga.audDat[1][ch]=val>>8; + audDat[0][ch]=val&0xff; + audDat[1][ch]=val>>8; break; } - if (updateDMA && !amiga.audEn[ch]) { + if (updateDMA && !mustDMA[ch]) { UPDATE_DMA(ch); } } @@ -349,6 +348,20 @@ void DivPlatformAmiga::rWrite(unsigned short addr, unsigned short val) { } } +void DivPlatformAmiga::rWrite(unsigned short addr, unsigned short val) { + if (addr&1) return; + + //logV("%.3x = %.4x",addr,val); + if (!skipRegisterWrites) { + writes.push(QueuedWrite(addr,val)); + regPool[addr>>1]=val; + + if (dumpWrites) { + addWrite(addr,val); + } + } +} + void DivPlatformAmiga::updateWave(int ch) { for (int i=0; i=0 && chan[i].samplesong.sampleLen) { @@ -520,10 +540,6 @@ void DivPlatformAmiga::tick(bool sysTick) { chan[i].writeVol=false; chWrite(i,8,chan[i].outVol); } - if (chan[i].updateWave) { - chan[i].updateWave=false; - updateWave(i); - } } if (updateADKCon) { @@ -717,6 +733,7 @@ void DivPlatformAmiga::muteChannel(int ch, bool mute) { } void DivPlatformAmiga::forceIns() { + logV("at time of clear: %d",writes.size()); for (int i=0; i<4; i++) { chan[i].insChanged=true; chan[i].freqChanged=true; @@ -738,6 +755,7 @@ DivDispatchOscBuffer* DivPlatformAmiga::getOscBuffer(int ch) { } void DivPlatformAmiga::reset() { + writes.clear(); memset(regPool,0,256*sizeof(unsigned short)); for (int i=0; i<4; i++) { chan[i]=DivPlatformAmiga::Channel(); @@ -750,6 +768,7 @@ void DivPlatformAmiga::reset() { filterOn=false; filtConst=filterOn?filtConstOn:filtConstOff; updateADKCon=true; + delay=0; amiga=Amiga(); // enable DMA diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index a05a5994d..903d7bd31 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -21,6 +21,7 @@ #define _AMIGA_H #include "../dispatch.h" +#include "../../fixedQueue.h" #include "../waveSynth.h" class DivPlatformAmiga: public DivDispatch { @@ -59,12 +60,14 @@ class DivPlatformAmiga: public DivDispatch { bool amigaModel; bool filterOn; bool updateADKCon; + short delay; struct Amiga { // register state bool audInt[4]; // interrupt on bool audIr[4]; // interrupt request bool audEn[4]; // audio DMA on + bool mustDMA[4]; // audio DMA must run bool useP[4]; // period modulation bool useV[4]; // volume modulation @@ -91,6 +94,8 @@ class DivPlatformAmiga: public DivDispatch { unsigned short hPos; // horizontal position of beam unsigned char state[4]; // current channel state + void write(unsigned short addr, unsigned short val); + Amiga() { memset(this,0,sizeof(*this)); } @@ -113,6 +118,14 @@ class DivPlatformAmiga: public DivDispatch { int sep1, sep2; + struct QueuedWrite { + unsigned short addr; + unsigned short val; + QueuedWrite(): addr(0), val(9) {} + QueuedWrite(unsigned short a, unsigned short v): addr(a), val(v) {} + }; + FixedQueue writes; + friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); friend class DivExportAmigaValidation;