HOW IS THIS LESS OPTIMAL - DO NOT USE!!!

THIS FAILS HORRIBLY... I am trying to do a global search
This commit is contained in:
tildearrow 2025-04-08 19:52:26 -05:00
parent d4e34db5b6
commit 876bb3cc5c

View file

@ -578,6 +578,38 @@ int estimateBlockSize(unsigned char* buf, size_t len, unsigned char* speedDial)
return ret; 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) { void reloc(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr, unsigned char* speedDial) {
unsigned int delta=destAddr-sourceAddr; unsigned int delta=destAddr-sourceAddr;
@ -997,6 +1029,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
unsigned char sortedCmd[16]; unsigned char sortedCmd[16];
unsigned char sortedDelay[16]; unsigned char sortedDelay[16];
SafeWriter* globalStream;
SafeWriter* chanStream[DIV_MAX_CHANS]; SafeWriter* chanStream[DIV_MAX_CHANS];
unsigned int chanStreamOff[DIV_MAX_CHANS]; unsigned int chanStreamOff[DIV_MAX_CHANS];
std::vector<size_t> tickPos[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; SafeWriter* w=new SafeWriter;
w->init(); w->init();
globalStream=new SafeWriter;
globalStream->init();
// write header // write header
w->write("FCS",4); w->write("FCS",4);
w->writeI(chans); w->writeI(chans);
@ -1038,6 +1074,18 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
double curDivider=divider; double curDivider=divider;
// PASS 0: play the song and log channel command streams // 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) { while (!done) {
for (int i=0; i<chans; i++) { for (int i=0; i<chans; i++) {
tickPos[i].push_back(chanStream[i]->tell()); 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) { if ((ticks-((tempoAccum+virtualTempoN)/virtualTempoD))<=0) {
logI("loop is on tick %d",tick); logI("loop is on tick %d",tick);
loopTick=tick; loopTick=tick;
// marker // loop marker
for (int i=0; i<chans; i++) { for (int i=0; i<chans; i++) {
chanStream[i]->writeC(0xf0); chanStream[i]->writeC(0xf0);
chanStream[i]->writeC(0x01);
chanStream[i]->writeC(0x00); chanStream[i]->writeC(0x00);
chanStream[i]->writeC(0x00); chanStream[i]->writeC(i);
chanStream[i]->writeC(0x00);
// padding // padding
chanStream[i]->writeC(0x00); chanStream[i]->writeC(0x00);
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]); 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)) { if (!(disablePasses&4)) {
for (int h=0; h<chans; h++) {
std::vector<SafeWriter*> subBlocks; 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 // 6 is the minimum size that can be reliably optimized
logI("finding sub-blocks in chan %d",h); logI("finding sub-blocks");
chanStream[h]=findSubBlocks(chanStream[h],subBlocks,sortedCmd); globalStream=findSubBlocks(globalStream,subBlocks,sortedCmd);
// find sub-blocks within sub-blocks // find sub-blocks within sub-blocks
size_t subBlocksLast=0; size_t subBlocksLast=0;
size_t subBlocksLen=subBlocks.size(); size_t subBlocksLen=subBlocks.size();
logI("finding sub-blocks within sub-blocks",h); logI("finding sub-blocks within sub-blocks");
while (subBlocksLast!=subBlocksLen) { while (subBlocksLast!=subBlocksLen) {
logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast); logI("got %d blocks... starting from %d",(int)subBlocksLen,(int)subBlocksLast);
for (size_t i=subBlocksLast; i<subBlocksLen; i++) { 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 // 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); globalStream->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];
@ -1344,10 +1401,10 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, unsigned int disable
blockOff.push_back(blockOff[dupOf]); blockOff.push_back(blockOff[dupOf]);
} else { } else {
// write sub-block // write sub-block
blockOff.push_back(chanStream[h]->tell()); blockOff.push_back(globalStream->tell());
logV("block size: %d",(int)block->size()); logV("block size: %d",(int)block->size());
assert(!(block->size()&7)); 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(); subBlocks.clear();
// resolve symbols // resolve symbols
unsigned char* buf=chanStream[h]->getFinalBuf(); unsigned char* buf=globalStream->getFinalBuf();
for (size_t j=0; j<chanStream[h]->size(); j+=8) { for (size_t j=0; j<globalStream->size(); j+=8) {
if (buf[j]==0xf4) { // callsym if (buf[j]==0xf4) { // callsym
unsigned int addr=buf[j+1]|(buf[j+2]<<8)|(buf[j+3]<<16)|(buf[j+4]<<24); unsigned int addr=buf[j+1]|(buf[j+2]<<8)|(buf[j+3]<<16)|(buf[j+4]<<24);
if (addr<blockOff.size()) { 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); logI("(before: %d - after: %d)",(int)beforeSize,(int)afterSize);
assert(!(chanStream[h]->size()&7)); assert(!(globalStream->size()&7));
}
} }
// PASS 5: remove nop's (again) // PASS 6: remove nop's (again)
for (int h=0; h<chans; h++) { globalStream=stripNops(globalStream);
chanStream[h]=stripNops(chanStream[h]);
}
// PASS 6: pack streams // PASS 7: pack stream
for (int h=0; h<chans; h++) { globalStream=packStream(globalStream,sortedCmd);
chanStream[h]=packStream(chanStream[h],sortedCmd);
}
// write results // write results
for (int i=0; i<chans; i++) { // TODO: FUCK THIS
chanStreamOff[i]=w->tell(); w->write(globalStream->getFinalBuf(),globalStream->size());
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];
}
w->seek(8,SEEK_SET); w->seek(8,SEEK_SET);
for (int i=0; i<chans; i++) { for (int i=0; i<chans; i++) {