From 27cde60f0b3591975ea44bd5e7e0bdf65ab44edc Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 7 Apr 2025 00:20:48 -0500 Subject: [PATCH] prepare to allow disable opt passes --- src/engine/cmdStream.h | 8 + src/engine/cmdStreamOps.cpp | 450 ++++++++++++++++++------------------ src/engine/engine.h | 2 +- 3 files changed, 235 insertions(+), 225 deletions(-) diff --git a/src/engine/cmdStream.h b/src/engine/cmdStream.h index 90ba5a0b3..72f458067 100644 --- a/src/engine/cmdStream.h +++ b/src/engine/cmdStream.h @@ -103,6 +103,14 @@ class DivCSPlayer { stream(buf,len) {} }; +struct DivCSProgress { + int stage, count, total; + DivCSProgress(): + stage(0), + count(0), + total(0) {} +}; + // command stream utilities namespace DivCS { int getCmdLength(unsigned char ext); diff --git a/src/engine/cmdStreamOps.cpp b/src/engine/cmdStreamOps.cpp index 965fcdbeb..e16a6b876 100644 --- a/src/engine/cmdStreamOps.cpp +++ b/src/engine/cmdStreamOps.cpp @@ -21,8 +21,6 @@ #include "../ta-log.h" #include -//#define DISABLE_BLOCK_SEARCH - int DivCS::getCmdLength(unsigned char ext) { switch (ext) { case DIV_CMD_SAMPLE_MODE: @@ -673,7 +671,7 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector& subBlock for (size_t groupSize=stream->size()>>1; groupSize>=8; groupSize--) { //for (size_t groupSize=7; groupSize<=stream->size()>>1; groupSize++) { bool foundSomething=false; - //logD("...try size %d",groupSize); + logV("...try size %d",groupSize); for (size_t searchPos=0; (searchPos+groupSize)size();) { const unsigned char* group=&buf[searchPos]; size_t groupLen=0; @@ -792,7 +790,7 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector& subBlock return stream; } -SafeWriter* DivEngine::saveCommand() { +SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disablePasses) { stop(); repeatPattern=false; shallStop=false; @@ -932,155 +930,159 @@ SafeWriter* DivEngine::saveCommand() { BUSY_END; // PASS 1: optimize command calls - // calculate command usage - int sortCand=-1; - int sortPos=0; - while (sortPos<16) { - sortCand=-1; - for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) { - if (cmdPopularity[i]) { - if (sortCand==-1) { - sortCand=i; - } else if (cmdPopularity[sortCand]getFinalBuf(); - for (size_t i=0; isize();) { - int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd); - if (insLen<1) { - logE("INS %x NOT IMPLEMENTED...",buf[i]); - break; - } - if (buf[i]==0xf7) { - // find whether this command is in speed dial - for (int j=0; j<16; j++) { - if (buf[i+1]==sortedCmd[j]) { - buf[i]=0xd0+j; - // move everything to the left - for (int k=i+2; k<(int)i+insLen; k++) { - buf[k-1]=buf[k]; - } - // put a nop - buf[i+insLen-1]=0xf1; - break; + if (!(disablePasses&1)) { + // calculate command usage + int sortCand=-1; + int sortPos=0; + while (sortPos<16) { + sortCand=-1; + for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) { + if (cmdPopularity[i]) { + if (sortCand==-1) { + sortCand=i; + } else if (cmdPopularity[sortCand]getFinalBuf(); + for (size_t i=0; isize();) { + int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd); + if (insLen<1) { + logE("INS %x NOT IMPLEMENTED...",buf[i]); + break; + } + if (buf[i]==0xf7) { + // find whether this command is in speed dial + for (int j=0; j<16; j++) { + if (buf[i+1]==sortedCmd[j]) { + buf[i]=0xd0+j; + // move everything to the left + for (int k=i+2; k<(int)i+insLen; k++) { + buf[k-1]=buf[k]; + } + // put a nop + buf[i+insLen-1]=0xf1; + break; + } + } + } + i+=insLen; + } } } // PASS 2: condense delays - // calculate delay usage - for (int h=0; hgetFinalBuf(); - int delayCount=0; - for (size_t i=0; isize();) { - int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd); - if (insLen<1) { - logE("INS %x NOT IMPLEMENTED...",buf[i]); - break; - } - if (buf[i]==0xfe) { - delayCount++; - } else { - if (delayCount>1 && delayCount<=255) { - delayPopularity[delayCount]++; + if (!(disablePasses&2)) { + // calculate delay usage + for (int h=0; hgetFinalBuf(); + int delayCount=0; + for (size_t i=0; isize();) { + int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd); + if (insLen<1) { + logE("INS %x NOT IMPLEMENTED...",buf[i]); + break; } - delayCount=0; - } - i+=insLen; - } - } - - // preset delays - sortCand=-1; - sortPos=0; - while (sortPos<16) { - sortCand=-1; - for (int i=0; i<256; i++) { - if (delayPopularity[i]) { - if (sortCand==-1) { - sortCand=i; - } else if (delayPopularity[sortCand]getFinalBuf(); - int delayPos=-1; - int delayCount=0; - int delayLast=0; - for (size_t i=0; isize();) { - int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd); - if (insLen<1) { - logE("INS %x NOT IMPLEMENTED...",buf[i]); - break; - } - if (buf[i]==0xfe) { - if (delayPos==-1) delayPos=i; - delayCount++; - delayLast=i; - } else { - // finish the last delay if any - if (delayPos!=-1) { - if (delayCount>1) { - if (delayLast255) { - buf[delayPos++]=0xfc; - buf[delayPos++]=delayCount&0xff; - buf[delayPos++]=(delayCount>>8)&0xff; - } else { - bool foundShort=false; - for (int j=0; j<16; j++) { - if (sortedDelay[j]==delayCount) { - buf[delayPos++]=0xe0+j; - foundShort=true; - break; - } - } - if (!foundShort) { - buf[delayPos++]=0xfd; - buf[delayPos++]=delayCount; - } - } - // fill with nop - for (int j=delayPos; j<=delayLast; j++) { - buf[j]=0xf1; - } - } + if (buf[i]==0xfe) { + delayCount++; + } else { + if (delayCount>1 && delayCount<=255) { + delayPopularity[delayCount]++; } - delayPos=-1; delayCount=0; } + i+=insLen; + } + } + + // preset delays + int sortCand=-1; + int sortPos=0; + while (sortPos<16) { + sortCand=-1; + for (int i=0; i<256; i++) { + if (delayPopularity[i]) { + if (sortCand==-1) { + sortCand=i; + } else if (delayPopularity[sortCand]getFinalBuf(); + int delayPos=-1; + int delayCount=0; + int delayLast=0; + for (size_t i=0; isize();) { + int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd); + if (insLen<1) { + logE("INS %x NOT IMPLEMENTED...",buf[i]); + break; + } + if (buf[i]==0xfe) { + if (delayPos==-1) delayPos=i; + delayCount++; + delayLast=i; + } else { + // finish the last delay if any + if (delayPos!=-1) { + if (delayCount>1) { + if (delayLast255) { + buf[delayPos++]=0xfc; + buf[delayPos++]=delayCount&0xff; + buf[delayPos++]=(delayCount>>8)&0xff; + } else { + bool foundShort=false; + for (int j=0; j<16; j++) { + if (sortedDelay[j]==delayCount) { + buf[delayPos++]=0xe0+j; + foundShort=true; + break; + } + } + if (!foundShort) { + buf[delayPos++]=0xfd; + buf[delayPos++]=delayCount; + } + } + // fill with nop + for (int j=delayPos; j<=delayLast; j++) { + buf[j]=0xf1; + } + } + } + delayPos=-1; + delayCount=0; + } + } + i+=insLen; } - i+=insLen; } } @@ -1090,101 +1092,101 @@ SafeWriter* DivEngine::saveCommand() { chanStream[h]=stripNops(chanStream[h],sortedCmd); } -#ifndef DISABLE_BLOCK_SEARCH // PASS 4: find sub-blocks and isolate them - for (int h=0; h subBlocks; - size_t beforeSize=chanStream[h]->size(); - - // 6 is the minimum size that can be reliably optimized - logI("finding sub-blocks in chan %d",h); - chanStream[h]=findSubBlocks(chanStream[h],subBlocks,sortedCmd); - // find sub-blocks within sub-blocks - size_t subBlocksLast=0; - size_t subBlocksLen=subBlocks.size(); - logI("finding sub-blocks within sub-blocks",h); - while (subBlocksLast!=subBlocksLen) { - logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast); - for (size_t i=subBlocksLast; i subBlocks; + size_t beforeSize=chanStream[h]->size(); + + // 6 is the minimum size that can be reliably optimized + logI("finding sub-blocks in chan %d",h); + chanStream[h]=findSubBlocks(chanStream[h],subBlocks,sortedCmd); + // find sub-blocks within sub-blocks + size_t subBlocksLast=0; + size_t subBlocksLen=subBlocks.size(); + logI("finding sub-blocks within sub-blocks",h); + while (subBlocksLast!=subBlocksLen) { + logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast); + for (size_t i=subBlocksLast; i blockOff; - chanStream[h]->seek(0,SEEK_END); - for (size_t i=0; i blockOff; + chanStream[h]->seek(0,SEEK_END); + for (size_t i=0; isize()==subBlocks[i]->size()) { - if (memcmp(subBlocks[j]->getFinalBuf(),subBlocks[i]->getFinalBuf(),subBlocks[j]->size())==0) { - logW("we have one"); - dupOf=j; - break; + // check whether this block is duplicate + int dupOf=-1; + for (size_t j=0; jsize()==subBlocks[i]->size()) { + if (memcmp(subBlocks[j]->getFinalBuf(),subBlocks[i]->getFinalBuf(),subBlocks[j]->size())==0) { + logW("we have one"); + dupOf=j; + break; + } } } - } - if (dupOf>=0) { - // push address of original block (discard duplicate) - blockOff.push_back(blockOff[dupOf]); - } else { - // write sub-block - blockOff.push_back(chanStream[h]->tell()); - chanStream[h]->write(block->getFinalBuf(),block->size()); - } - } - - for (SafeWriter* block: subBlocks) { - block->finish(); - delete block; - } - subBlocks.clear(); - - // resolve symbols - unsigned char* buf=chanStream[h]->getFinalBuf(); - for (size_t j=0; jsize();) { - int insLen=getInsLength(buf[j],_EXT(buf,j,chanStream[h]->size()),sortedCmd); - if (insLen<1) { - logE("INS %x NOT IMPLEMENTED...",buf[j]); - break; - } - if (buf[j]==0xf4) { // callsym - unsigned int addr=buf[j+1]|(buf[j+2]<<8)|(buf[j+3]<<16)|(buf[j+4]<<24); - if (addr>8)&0xff; - buf[j+3]=0xf1; - buf[j+4]=0xf1; - } else { - buf[j]=0xf5; - buf[j+1]=addr&0xff; - buf[j+2]=(addr>>8)&0xff; - buf[j+3]=(addr>>16)&0xff; - buf[j+4]=(addr>>24)&0xff; - } + if (dupOf>=0) { + // push address of original block (discard duplicate) + blockOff.push_back(blockOff[dupOf]); } else { - logE("requested symbol %d is out of bounds!",addr); + // write sub-block + blockOff.push_back(chanStream[h]->tell()); + chanStream[h]->write(block->getFinalBuf(),block->size()); } } - j+=insLen; - } - size_t afterSize=chanStream[h]->size(); - logI("(before: %d - after: %d)",(int)beforeSize,(int)afterSize); + for (SafeWriter* block: subBlocks) { + block->finish(); + delete block; + } + subBlocks.clear(); + + // resolve symbols + unsigned char* buf=chanStream[h]->getFinalBuf(); + for (size_t j=0; jsize();) { + int insLen=getInsLength(buf[j],_EXT(buf,j,chanStream[h]->size()),sortedCmd); + if (insLen<1) { + logE("INS %x NOT IMPLEMENTED...",buf[j]); + break; + } + if (buf[j]==0xf4) { // callsym + unsigned int addr=buf[j+1]|(buf[j+2]<<8)|(buf[j+3]<<16)|(buf[j+4]<<24); + if (addr>8)&0xff; + buf[j+3]=0xf1; + buf[j+4]=0xf1; + } else { + buf[j]=0xf5; + buf[j+1]=addr&0xff; + buf[j+2]=(addr>>8)&0xff; + buf[j+3]=(addr>>16)&0xff; + buf[j+4]=(addr>>24)&0xff; + } + } else { + logE("requested symbol %d is out of bounds!",addr); + } + } + j+=insLen; + } + + size_t afterSize=chanStream[h]->size(); + logI("(before: %d - after: %d)",(int)beforeSize,(int)afterSize); + } } -#endif // PASS 5: remove nop's (again) for (int h=0; h