prepare to allow disable opt passes
This commit is contained in:
parent
e9911ab0aa
commit
27cde60f0b
|
@ -103,6 +103,14 @@ class DivCSPlayer {
|
||||||
stream(buf,len) {}
|
stream(buf,len) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DivCSProgress {
|
||||||
|
int stage, count, total;
|
||||||
|
DivCSProgress():
|
||||||
|
stage(0),
|
||||||
|
count(0),
|
||||||
|
total(0) {}
|
||||||
|
};
|
||||||
|
|
||||||
// command stream utilities
|
// command stream utilities
|
||||||
namespace DivCS {
|
namespace DivCS {
|
||||||
int getCmdLength(unsigned char ext);
|
int getCmdLength(unsigned char ext);
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
#include "../ta-log.h"
|
#include "../ta-log.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
//#define DISABLE_BLOCK_SEARCH
|
|
||||||
|
|
||||||
int DivCS::getCmdLength(unsigned char ext) {
|
int DivCS::getCmdLength(unsigned char ext) {
|
||||||
switch (ext) {
|
switch (ext) {
|
||||||
case DIV_CMD_SAMPLE_MODE:
|
case DIV_CMD_SAMPLE_MODE:
|
||||||
|
@ -673,7 +671,7 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
||||||
for (size_t groupSize=stream->size()>>1; groupSize>=8; groupSize--) {
|
for (size_t groupSize=stream->size()>>1; groupSize>=8; groupSize--) {
|
||||||
//for (size_t groupSize=7; groupSize<=stream->size()>>1; groupSize++) {
|
//for (size_t groupSize=7; groupSize<=stream->size()>>1; groupSize++) {
|
||||||
bool foundSomething=false;
|
bool foundSomething=false;
|
||||||
//logD("...try size %d",groupSize);
|
logV("...try size %d",groupSize);
|
||||||
for (size_t searchPos=0; (searchPos+groupSize)<stream->size();) {
|
for (size_t searchPos=0; (searchPos+groupSize)<stream->size();) {
|
||||||
const unsigned char* group=&buf[searchPos];
|
const unsigned char* group=&buf[searchPos];
|
||||||
size_t groupLen=0;
|
size_t groupLen=0;
|
||||||
|
@ -792,7 +790,7 @@ SafeWriter* findSubBlocks(SafeWriter* stream, std::vector<SafeWriter*>& subBlock
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeWriter* DivEngine::saveCommand() {
|
SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disablePasses) {
|
||||||
stop();
|
stop();
|
||||||
repeatPattern=false;
|
repeatPattern=false;
|
||||||
shallStop=false;
|
shallStop=false;
|
||||||
|
@ -932,155 +930,159 @@ SafeWriter* DivEngine::saveCommand() {
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
|
|
||||||
// PASS 1: optimize command calls
|
// PASS 1: optimize command calls
|
||||||
// calculate command usage
|
if (!(disablePasses&1)) {
|
||||||
int sortCand=-1;
|
// calculate command usage
|
||||||
int sortPos=0;
|
int sortCand=-1;
|
||||||
while (sortPos<16) {
|
int sortPos=0;
|
||||||
sortCand=-1;
|
while (sortPos<16) {
|
||||||
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
sortCand=-1;
|
||||||
if (cmdPopularity[i]) {
|
for (int i=DIV_CMD_SAMPLE_MODE; i<256; i++) {
|
||||||
if (sortCand==-1) {
|
if (cmdPopularity[i]) {
|
||||||
sortCand=i;
|
if (sortCand==-1) {
|
||||||
} else if (cmdPopularity[sortCand]<cmdPopularity[i]) {
|
sortCand=i;
|
||||||
sortCand=i;
|
} else if (cmdPopularity[sortCand]<cmdPopularity[i]) {
|
||||||
}
|
sortCand=i;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sortCand==-1) break;
|
|
||||||
|
|
||||||
sortedCmdPopularity[sortPos]=cmdPopularity[sortCand];
|
|
||||||
sortedCmd[sortPos]=sortCand;
|
|
||||||
cmdPopularity[sortCand]=0;
|
|
||||||
sortPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set speed dial commands (TODO)
|
|
||||||
for (int h=0; h<chans; h++) {
|
|
||||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
|
||||||
for (size_t i=0; i<chanStream[h]->size();) {
|
|
||||||
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;
|
if (sortCand==-1) break;
|
||||||
|
|
||||||
|
sortedCmdPopularity[sortPos]=cmdPopularity[sortCand];
|
||||||
|
sortedCmd[sortPos]=sortCand;
|
||||||
|
cmdPopularity[sortCand]=0;
|
||||||
|
sortPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set speed dial commands
|
||||||
|
for (int h=0; h<chans; h++) {
|
||||||
|
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||||
|
for (size_t i=0; i<chanStream[h]->size();) {
|
||||||
|
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
|
// PASS 2: condense delays
|
||||||
// calculate delay usage
|
if (!(disablePasses&2)) {
|
||||||
for (int h=0; h<chans; h++) {
|
// calculate delay usage
|
||||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
for (int h=0; h<chans; h++) {
|
||||||
int delayCount=0;
|
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||||
for (size_t i=0; i<chanStream[h]->size();) {
|
int delayCount=0;
|
||||||
int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd);
|
for (size_t i=0; i<chanStream[h]->size();) {
|
||||||
if (insLen<1) {
|
int insLen=getInsLength(buf[i],_EXT(buf,i,chanStream[h]->size()),sortedCmd);
|
||||||
logE("INS %x NOT IMPLEMENTED...",buf[i]);
|
if (insLen<1) {
|
||||||
break;
|
logE("INS %x NOT IMPLEMENTED...",buf[i]);
|
||||||
}
|
break;
|
||||||
if (buf[i]==0xfe) {
|
|
||||||
delayCount++;
|
|
||||||
} else {
|
|
||||||
if (delayCount>1 && delayCount<=255) {
|
|
||||||
delayPopularity[delayCount]++;
|
|
||||||
}
|
}
|
||||||
delayCount=0;
|
if (buf[i]==0xfe) {
|
||||||
}
|
delayCount++;
|
||||||
i+=insLen;
|
} else {
|
||||||
}
|
if (delayCount>1 && delayCount<=255) {
|
||||||
}
|
delayPopularity[delayCount]++;
|
||||||
|
|
||||||
// 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]<delayPopularity[i]) {
|
|
||||||
sortCand=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sortCand==-1) break;
|
|
||||||
|
|
||||||
sortedDelayPopularity[sortPos]=delayPopularity[sortCand];
|
|
||||||
sortedDelay[sortPos]=sortCand;
|
|
||||||
delayPopularity[sortCand]=0;
|
|
||||||
sortPos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// condense delays
|
|
||||||
for (int h=0; h<chans; h++) {
|
|
||||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
|
||||||
int delayPos=-1;
|
|
||||||
int delayCount=0;
|
|
||||||
int delayLast=0;
|
|
||||||
for (size_t i=0; i<chanStream[h]->size();) {
|
|
||||||
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 (delayLast<delayPos) {
|
|
||||||
logE("delayLast<delayPos! %d<%d",delayLast,delayPos);
|
|
||||||
} else {
|
|
||||||
// write condensed delay and fill the rest with nop
|
|
||||||
if (delayCount>255) {
|
|
||||||
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;
|
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]<delayPopularity[i]) {
|
||||||
|
sortCand=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sortCand==-1) break;
|
||||||
|
|
||||||
|
sortedDelayPopularity[sortPos]=delayPopularity[sortCand];
|
||||||
|
sortedDelay[sortPos]=sortCand;
|
||||||
|
delayPopularity[sortCand]=0;
|
||||||
|
sortPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// condense delays
|
||||||
|
for (int h=0; h<chans; h++) {
|
||||||
|
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||||
|
int delayPos=-1;
|
||||||
|
int delayCount=0;
|
||||||
|
int delayLast=0;
|
||||||
|
for (size_t i=0; i<chanStream[h]->size();) {
|
||||||
|
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 (delayLast<delayPos) {
|
||||||
|
logE("delayLast<delayPos! %d<%d",delayLast,delayPos);
|
||||||
|
} else {
|
||||||
|
// write condensed delay and fill the rest with nop
|
||||||
|
if (delayCount>255) {
|
||||||
|
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);
|
chanStream[h]=stripNops(chanStream[h],sortedCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DISABLE_BLOCK_SEARCH
|
|
||||||
// PASS 4: find sub-blocks and isolate them
|
// PASS 4: find sub-blocks and isolate them
|
||||||
for (int h=0; h<chans; h++) {
|
if (!(disablePasses&4)) {
|
||||||
std::vector<SafeWriter*> subBlocks;
|
for (int h=0; h<chans; h++) {
|
||||||
size_t beforeSize=chanStream[h]->size();
|
std::vector<SafeWriter*> 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);
|
// 6 is the minimum size that can be reliably optimized
|
||||||
chanStream[h]=findSubBlocks(chanStream[h],subBlocks,sortedCmd);
|
logI("finding sub-blocks in chan %d",h);
|
||||||
// find sub-blocks within sub-blocks
|
chanStream[h]=findSubBlocks(chanStream[h],subBlocks,sortedCmd);
|
||||||
size_t subBlocksLast=0;
|
// find sub-blocks within sub-blocks
|
||||||
size_t subBlocksLen=subBlocks.size();
|
size_t subBlocksLast=0;
|
||||||
logI("finding sub-blocks within sub-blocks",h);
|
size_t subBlocksLen=subBlocks.size();
|
||||||
while (subBlocksLast!=subBlocksLen) {
|
logI("finding sub-blocks within sub-blocks",h);
|
||||||
logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast);
|
while (subBlocksLast!=subBlocksLen) {
|
||||||
for (size_t i=subBlocksLast; i<subBlocksLen; i++) {
|
logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast);
|
||||||
SafeWriter* newBlock=findSubBlocks(subBlocks[i],subBlocks,sortedCmd);
|
for (size_t i=subBlocksLast; i<subBlocksLen; i++) {
|
||||||
subBlocks[i]=newBlock;
|
SafeWriter* newBlock=findSubBlocks(subBlocks[i],subBlocks,sortedCmd);
|
||||||
|
subBlocks[i]=newBlock;
|
||||||
|
}
|
||||||
|
subBlocksLast=subBlocksLen;
|
||||||
|
subBlocksLen=subBlocks.size();
|
||||||
}
|
}
|
||||||
subBlocksLast=subBlocksLen;
|
|
||||||
subBlocksLen=subBlocks.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert sub-blocks and resolve symbols
|
// insert sub-blocks and resolve symbols
|
||||||
logI("%d sub-blocks total",(int)subBlocks.size());
|
logI("%d sub-blocks total",(int)subBlocks.size());
|
||||||
std::vector<size_t> blockOff;
|
std::vector<size_t> blockOff;
|
||||||
chanStream[h]->seek(0,SEEK_END);
|
chanStream[h]->seek(0,SEEK_END);
|
||||||
for (size_t i=0; i<subBlocks.size(); i++) {
|
for (size_t i=0; i<subBlocks.size(); i++) {
|
||||||
SafeWriter* block=subBlocks[i];
|
SafeWriter* block=subBlocks[i];
|
||||||
|
|
||||||
// check whether this block is duplicate
|
// check whether this block is duplicate
|
||||||
int dupOf=-1;
|
int dupOf=-1;
|
||||||
for (size_t j=0; j<i; j++) {
|
for (size_t j=0; j<i; j++) {
|
||||||
if (subBlocks[j]->size()==subBlocks[i]->size()) {
|
if (subBlocks[j]->size()==subBlocks[i]->size()) {
|
||||||
if (memcmp(subBlocks[j]->getFinalBuf(),subBlocks[i]->getFinalBuf(),subBlocks[j]->size())==0) {
|
if (memcmp(subBlocks[j]->getFinalBuf(),subBlocks[i]->getFinalBuf(),subBlocks[j]->size())==0) {
|
||||||
logW("we have one");
|
logW("we have one");
|
||||||
dupOf=j;
|
dupOf=j;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (dupOf>=0) {
|
if (dupOf>=0) {
|
||||||
// push address of original block (discard duplicate)
|
// push address of original block (discard duplicate)
|
||||||
blockOff.push_back(blockOff[dupOf]);
|
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; j<chanStream[h]->size();) {
|
|
||||||
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<blockOff.size()) {
|
|
||||||
// turn it into call
|
|
||||||
addr=blockOff[addr];
|
|
||||||
if (addr<=0xffff) {
|
|
||||||
buf[j]=0xf8;
|
|
||||||
buf[j+1]=addr&0xff;
|
|
||||||
buf[j+2]=(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 {
|
} 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();
|
for (SafeWriter* block: subBlocks) {
|
||||||
logI("(before: %d - after: %d)",(int)beforeSize,(int)afterSize);
|
block->finish();
|
||||||
|
delete block;
|
||||||
|
}
|
||||||
|
subBlocks.clear();
|
||||||
|
|
||||||
|
// resolve symbols
|
||||||
|
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||||
|
for (size_t j=0; j<chanStream[h]->size();) {
|
||||||
|
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<blockOff.size()) {
|
||||||
|
// turn it into call
|
||||||
|
addr=blockOff[addr];
|
||||||
|
if (addr<=0xffff) {
|
||||||
|
buf[j]=0xf8;
|
||||||
|
buf[j+1]=addr&0xff;
|
||||||
|
buf[j+2]=(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)
|
// PASS 5: remove nop's (again)
|
||||||
for (int h=0; h<chans; h++) {
|
for (int h=0; h<chans; h++) {
|
||||||
|
|
|
@ -730,7 +730,7 @@ class DivEngine {
|
||||||
// dump to TIunA.
|
// dump to TIunA.
|
||||||
SafeWriter* saveTiuna(const bool* sysToExport, const char* baseLabel, int firstBankSize, int otherBankSize);
|
SafeWriter* saveTiuna(const bool* sysToExport, const char* baseLabel, int firstBankSize, int otherBankSize);
|
||||||
// dump command stream.
|
// dump command stream.
|
||||||
SafeWriter* saveCommand();
|
SafeWriter* saveCommand(DivCSProgress* progress=NULL, unsigned int disablePasses=0);
|
||||||
// export to text
|
// export to text
|
||||||
SafeWriter* saveText(bool separatePatterns=true);
|
SafeWriter* saveText(bool separatePatterns=true);
|
||||||
// export to an audio file
|
// export to an audio file
|
||||||
|
|
Loading…
Reference in a new issue