HOW IS THIS LESS OPTIMAL - DO NOT USE!!!
THIS FAILS HORRIBLY... I am trying to do a global search
This commit is contained in:
parent
d4e34db5b6
commit
876bb3cc5c
|
@ -578,6 +578,38 @@ int estimateBlockSize(unsigned char* buf, size_t len, unsigned char* speedDial)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void reloc8(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr) {
|
||||
unsigned int delta=destAddr-sourceAddr;
|
||||
for (size_t i=0; i<len; i+=8) {
|
||||
switch (buf[i]) {
|
||||
case 0xf5: // calli
|
||||
case 0xfa: { // jmp
|
||||
unsigned int addr=buf[i+1]|(buf[i+2]<<8)|(buf[i+3]<<16)|(buf[i+4]<<24);
|
||||
addr+=delta;
|
||||
buf[i+1]=addr&0xff;
|
||||
buf[i+2]=(addr>>8)&0xff;
|
||||
buf[i+3]=(addr>>16)&0xff;
|
||||
buf[i+4]=(addr>>24)&0xff;
|
||||
break;
|
||||
}
|
||||
case 0xf8: { // call
|
||||
unsigned int addr=buf[i+1]|(buf[i+2]<<8);
|
||||
addr+=delta;
|
||||
if (addr>0xffff) {
|
||||
buf[i]=0xf5;
|
||||
buf[i+1]=addr&0xff;
|
||||
buf[i+2]=(addr>>8)&0xff;
|
||||
buf[i+3]=(addr>>16)&0xff;
|
||||
buf[i+4]=(addr>>24)&0xff;
|
||||
} else {
|
||||
buf[i+1]=addr&0xff;
|
||||
buf[i+2]=(addr>>8)&0xff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reloc(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr, unsigned char* speedDial) {
|
||||
unsigned int delta=destAddr-sourceAddr;
|
||||
|
@ -997,6 +1029,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
unsigned char sortedCmd[16];
|
||||
unsigned char sortedDelay[16];
|
||||
|
||||
SafeWriter* globalStream;
|
||||
SafeWriter* chanStream[DIV_MAX_CHANS];
|
||||
unsigned int chanStreamOff[DIV_MAX_CHANS];
|
||||
std::vector<size_t> tickPos[DIV_MAX_CHANS];
|
||||
|
@ -1014,6 +1047,9 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
SafeWriter* w=new SafeWriter;
|
||||
w->init();
|
||||
|
||||
globalStream=new SafeWriter;
|
||||
globalStream->init();
|
||||
|
||||
// write header
|
||||
w->write("FCS",4);
|
||||
w->writeI(chans);
|
||||
|
@ -1038,6 +1074,18 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
double curDivider=divider;
|
||||
|
||||
// PASS 0: play the song and log channel command streams
|
||||
// song beginning marker
|
||||
for (int i=0; i<chans; i++) {
|
||||
chanStream[i]->writeC(0xf0);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(i);
|
||||
// padding
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
}
|
||||
while (!done) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
tickPos[i].push_back(chanStream[i]->tell());
|
||||
|
@ -1047,12 +1095,12 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
if ((ticks-((tempoAccum+virtualTempoN)/virtualTempoD))<=0) {
|
||||
logI("loop is on tick %d",tick);
|
||||
loopTick=tick;
|
||||
// marker
|
||||
// loop marker
|
||||
for (int i=0; i<chans; i++) {
|
||||
chanStream[i]->writeC(0xf0);
|
||||
chanStream[i]->writeC(0x01);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(i);
|
||||
// padding
|
||||
chanStream[i]->writeC(0x00);
|
||||
chanStream[i]->writeC(0x00);
|
||||
|
@ -1297,19 +1345,28 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
chanStream[h]=stripNops(chanStream[h]);
|
||||
}
|
||||
|
||||
// PASS 4: find sub-blocks and isolate them
|
||||
// PASS 4: put all channels together
|
||||
for (int i=0; i<chans; i++) {
|
||||
chanStreamOff[i]=w->tell();
|
||||
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
||||
reloc8(chanStream[i]->getFinalBuf(),chanStream[i]->size(),0,w->tell());
|
||||
globalStream->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
|
||||
chanStream[i]->finish();
|
||||
delete chanStream[i];
|
||||
}
|
||||
|
||||
// PASS 5: find sub-blocks and isolate them
|
||||
if (!(disablePasses&4)) {
|
||||
for (int h=0; h<chans; h++) {
|
||||
std::vector<SafeWriter*> subBlocks;
|
||||
size_t beforeSize=chanStream[h]->size();
|
||||
size_t beforeSize=globalStream->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);
|
||||
logI("finding sub-blocks");
|
||||
globalStream=findSubBlocks(globalStream,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);
|
||||
logI("finding sub-blocks within sub-blocks");
|
||||
while (subBlocksLast!=subBlocksLen) {
|
||||
logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast);
|
||||
for (size_t i=subBlocksLast; i<subBlocksLen; i++) {
|
||||
|
@ -1323,7 +1380,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
// insert sub-blocks and resolve symbols
|
||||
logI("%d sub-blocks total",(int)subBlocks.size());
|
||||
std::vector<size_t> blockOff;
|
||||
chanStream[h]->seek(0,SEEK_END);
|
||||
globalStream->seek(0,SEEK_END);
|
||||
for (size_t i=0; i<subBlocks.size(); i++) {
|
||||
SafeWriter* block=subBlocks[i];
|
||||
|
||||
|
@ -1344,10 +1401,10 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
blockOff.push_back(blockOff[dupOf]);
|
||||
} else {
|
||||
// write sub-block
|
||||
blockOff.push_back(chanStream[h]->tell());
|
||||
blockOff.push_back(globalStream->tell());
|
||||
logV("block size: %d",(int)block->size());
|
||||
assert(!(block->size()&7));
|
||||
chanStream[h]->write(block->getFinalBuf(),block->size());
|
||||
globalStream->write(block->getFinalBuf(),block->size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1358,8 +1415,8 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
subBlocks.clear();
|
||||
|
||||
// resolve symbols
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
for (size_t j=0; j<chanStream[h]->size(); j+=8) {
|
||||
unsigned char* buf=globalStream->getFinalBuf();
|
||||
for (size_t j=0; j<globalStream->size(); j+=8) {
|
||||
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()) {
|
||||
|
@ -1376,31 +1433,20 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
|
|||
}
|
||||
}
|
||||
|
||||
size_t afterSize=chanStream[h]->size();
|
||||
size_t afterSize=globalStream->size();
|
||||
logI("(before: %d - after: %d)",(int)beforeSize,(int)afterSize);
|
||||
assert(!(chanStream[h]->size()&7));
|
||||
}
|
||||
assert(!(globalStream->size()&7));
|
||||
}
|
||||
|
||||
// PASS 5: remove nop's (again)
|
||||
for (int h=0; h<chans; h++) {
|
||||
chanStream[h]=stripNops(chanStream[h]);
|
||||
}
|
||||
// PASS 6: remove nop's (again)
|
||||
globalStream=stripNops(globalStream);
|
||||
|
||||
// PASS 6: pack streams
|
||||
for (int h=0; h<chans; h++) {
|
||||
chanStream[h]=packStream(chanStream[h],sortedCmd);
|
||||
}
|
||||
// PASS 7: pack stream
|
||||
globalStream=packStream(globalStream,sortedCmd);
|
||||
|
||||
// write results
|
||||
for (int i=0; i<chans; i++) {
|
||||
chanStreamOff[i]=w->tell();
|
||||
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
||||
reloc(chanStream[i]->getFinalBuf(),chanStream[i]->size(),0,w->tell(),sortedCmd);
|
||||
w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size());
|
||||
chanStream[i]->finish();
|
||||
delete chanStream[i];
|
||||
}
|
||||
// TODO: FUCK THIS
|
||||
w->write(globalStream->getFinalBuf(),globalStream->size());
|
||||
|
||||
w->seek(8,SEEK_SET);
|
||||
for (int i=0; i<chans; i++) {
|
||||
|
|
Loading…
Reference in a new issue