diff --git a/papers/export-tech.md b/papers/export-tech.md index 77caae46f..3039cca37 100644 --- a/papers/export-tech.md +++ b/papers/export-tech.md @@ -71,6 +71,7 @@ hex | description ----|------------------------------------ f0 | UNUSED - placeholder used during optimization passes (3-byte nonce follows) f1 | no operation + f2 | UNUSED - unoptimized extended command f4 | call symbol (16-bit index follows; only used internally) f5 | jump to sub-block (address follows) f6 | go to sub-block (32-bit offset follows) diff --git a/src/engine/cmdStreamOps.cpp b/src/engine/cmdStreamOps.cpp index ac39ebc27..0cbfb7d0a 100644 --- a/src/engine/cmdStreamOps.cpp +++ b/src/engine/cmdStreamOps.cpp @@ -35,6 +35,47 @@ lastTick[x]=tick; \ */ +int getInsLength(unsigned char ins) { + switch (ins) { + case 0xb8: // ins + case 0xc0: // pre porta + case 0xc3: // vib range + case 0xc4: // vib shape + case 0xc5: // pitch + case 0xc7: // volume + case 0xca: // legato + case 0xfd: // waitc + return 2; + case 0xbe: // pan + case 0xc2: // vibrato + case 0xc6: // arpeggio + case 0xc8: // vol slide + case 0xc9: // porta + return 3; + // speed dial commands + case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: + case 0xdc: case 0xdd: case 0xde: case 0xdf: + return 0; + case 0xf0: // opt + return 4; + case 0xf2: // opt command + case 0xf7: // cmd + return 0; + case 0xf4: // callsym + case 0xf8: // callb16 + case 0xfc: // waits + return 3; + case 0xf5: // call + case 0xf6: // callb32 + case 0xfa: // jmp + case 0xfb: // rate + return 5; + } + return 1; +} + void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { switch (c.cmd) { case DIV_CMD_NOTE_ON: @@ -63,7 +104,8 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { w->writeC((unsigned char)c.cmd+0xb4); break; default: - w->writeC(0xf0); // unoptimized extended command + return; // quit for now... we'll implement this later + w->writeC(0xf2); // unoptimized extended command w->writeC(c.cmd); break; } @@ -204,6 +246,27 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) { void reloc(unsigned char* buf, size_t len, unsigned int sourceAddr, unsigned int destAddr) { // TODO... this is important! + unsigned int delta=destAddr-sourceAddr; + for (size_t i=0; i>8)&0xff; + buf[i+3]=(addr>>16)&0xff; + buf[i+4]=(addr>>24)&0xff; + break; + } + } + i+=insLen; + } } SafeWriter* DivEngine::saveCommand() { @@ -412,7 +475,7 @@ SafeWriter* DivEngine::saveCommand() { next=reader->readC(); chanStream[i]->writeC(next); break; - case 0xf0: { // full command (pre) + case 0xf2: { // full command (pre) unsigned char cmd=reader->readC(); bool foundShort=false; for (int j=0; j<16; j++) { @@ -494,6 +557,7 @@ SafeWriter* DivEngine::saveCommand() { for (int i=0; itell(); logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size()); + reloc(chanStream[i]->getFinalBuf(),chanStream[i]->size(),0,w->tell()); w->write(chanStream[i]->getFinalBuf(),chanStream[i]->size()); chanStream[i]->finish(); delete chanStream[i];